Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
VC_Lect.doc
Скачиваний:
6
Добавлен:
01.07.2025
Размер:
15 Мб
Скачать
☆

21.9.Еще одна иллюстрация некоторых алгоритмов на примере обработки числового массива

// AlgTest.cpp : Defines the entry point for the console application.

//

#include "stdafx.h"

#include "AlgTest.h"

#include <Conio.h>

#include <algorithm> // for_each, find, find_if

#include <vector>

#include <functional> // unary_function

#include <time.h>

const int VectorSize =5;

// GreaterThanTwo – (шаблон) объект-функция (предикат), которая возвращает

// значение true, если аргумент превышает значение 2

template <class T>

class GreaterThanTwo : public unary_function<T, bool>

{

public:

bool operator()(T& arg1)

{ return arg1>2; }

};

// ShowElement – шаблонная функция, печатающая значение итератора itor,

// указывающего на элемент последовательности Container. Если значение

// итератора "законечное", то функция выводит строку "Last element!"

template <class Container, class Iterator>

void ShowElement(Container & c, Iterator & itor)

{

if(itor!= c.end()) cout<<*itor; else cout<<"Last element!";

}

/////////////////////////////////////////////////////////////////

void DemoIntVec()

{

// ExitThread(0);

TCHAR szCurDir[MAX_PATH];

DWORD cchLength = GetFullPathName(TEXT("C:"), MAX_PATH, szCurDir, NULL);

wcout<<szCurDir;

/////////////////////////////////////

vector <int> vInt(VectorSize);

typedef vector <int>::iterator Itor;

for(int i=0; i<VectorSize; i++)vInt[i]=i;

Itor first = vInt.begin();

Itor last = vInt.end();

// вывести все элементы последовательности с помощью for_each

// и объекта-функции DoPrint

cout<<"Test method for_each()\n";

for_each(first,last,DoPrint); // 0 1 2 3 4

cout<<endl;

// найти первый элемент вектора, значение которого равно 2

Itor retItor=find(first,last,2);

cout<<"find(first,last,2)=";

ShowElement(vInt,retItor); //find(first,last,2)=2

cout<<endl;

// найти первый элемент вектора, значение которого равно 10

retItor=find(first,last,10);

cout<<"find(first,last,10)=";

ShowElement(vInt,retItor); //find(first,last,10)=Last element!

cout<<endl;

// найти первый элемент вектора, значение которого больше 2

GreaterThanTwo <int> isGreaterThanTwo;

retItor=find_if(first,last,isGreaterThanTwo);

cout<<"find_if(first,last,isGreaterThanTwo)=";

ShowElement(vInt,retItor);//find_if(first,last,isGreaterThanTwo)=3

cout<<endl;

// подсчитать число элементов вектора, значение которых равно 3

int retSize=count(first,last,3);

cout<<"count(first,last,3)="<<retSize<<endl; //count(first,last,3)=1

// подсчитать число элементов вектора, значение которых больше 2

retSize=count_if(first,last,isGreaterThanTwo);

cout<<"count_if(first,last,isGreaterThanTwo)="<<retSize<<endl;

//count_if(first,last,isGreaterThanTwo)=2

}

int RangedRand( int range_min, int range_max)

{

double res=(double)rand() / (RAND_MAX + 1) * (range_max - range_min) + range_min;

return static_cast<int>(res);

}

22.Профилирование программы в Microsoft Visual Studio 6.0

Под профилированием программы понимается получение и анализ статистики по времени выполнения функций или строк программы, количеству вызванных функций, числу вызовов функций и т.д. с целью сокращения времени выполнения программы в целом или отдельных ее фрагментов. Профилирование помогает выявить «узкие» места программы, т.е. критичные по времени выполнения.

Для профилирования в принципе можно использовать какие-либо свои собственные средства, например, фиксировать время работы программы с помощью секундомера или встраивать в программный код фиксацию времени и т.п., но это неэффективно и сопряжено с многими проблемами. Например, просто фиксация системного времени даст в общем случае большие погрешности, так как процессорное время Windows дает не только Вашему приложению. А если в приложении несколько потоков?

Одним словом, профилирование программы проще всего осуществить с использованием средства Profile Microsoft Visual C++ (профайлер), которое имеется в версиях Professional и Enterprise Editions.

Прежде всего, для профилирования программы выполните команду ProjectProject settings и на вкладке Link отметьте флажок Enable Profiling.

Далее выполните команду BuildProfile, в результате чего будет показано окно настроек профилирования (рис.1).

Рис. 1. Окно настроек профайлера

Смысл режимов профайлера следующий.

В режиме Function Timing профайлер фиксирует число вызoвов каждой функции (hit count) и время выполнения данной функции и вызываемых ею других функций. При выборе этого режима и выполнения программы (нажатия кнопки ОК) на вкладке Profile в окне Output появится информация вида:

Func Func+Child

Time % Time % Hit Count Function

------------------------------------------------------------

16,448 10,8 25,886 16,9 231071 _Destroy(double *)

…

Единица измерения времени указывается в окне вывода статистики и обычно это миллисекунды (мсек).

В столбце Func Time указывается время выполнения операторов функции без учета времени выполнения тех функций, которые она вызывает. В следующем столбце показывается то же время, но в процентах (от всего времени профилирования).

В столбце Func+Child Time указывается время выполнения данной функции в мсек. с учетом времени выполнения вызываемых ею функций, а в четвертом столбце – то же время, но в процентах.

В столбце Hit Count показывается число вызовов функции, а в следующем столбце – ее имя.

В режиме Function coverage профайлер фиксирует факт вызoва каждой функции. При выборе этого режима и выполнения программы на вкладке Profile в окне Output появится список всех функций программы, в том числе и вызываемых ими, и фактически вызванные функции будут отмечены символом *. Таким образом, этот режим позволяет выявить те участки кода, которые были фактически выполнены.

В режиме Line coverage профайлер показывает в своем окне все строки программного кода, в том числе и из включенных файлов, и отмечает символом * те из них, которые были фактически выполнены. Подобно режиму Function coverage, этот режим также позволяет выявить те участки кода, которые были фактически выполнены. Как можнопредположить, объем выводимых данных при этом будет весьма немалым.

В режиме Merge (слияние, объединение) профайлер позволяет выполнять многочисленные запуски программы с различными данными и в своем окне отображает накопленные данные. Для использования этого режима надо один раз выполнить прифилирование в любом другом режиме, а затем выбрать Merge и выполнять профилирование любое число раз. Таким образом, этот режим позволяет объединить результаты профилирования, полученные при выполнении программы с различными исходными данными (но с неизменным кодом, т.е. без перестройки программы).

Наконец, режим Custom позволяет указать пакетный файл (в поле ввода Custom Settings), в котором должны содержаться команды для профайлера (подробные сведения ­ – в MSDN).

В поле ввода Advanced Settings можно указать дополнительные команды для профайлера. Например, указание в этом поле строки вида

/EXCALL /INC file1.obj

означает, что из профилирования исключаются все объектные файлы и библиотеки (/EXCALL) и включается в профилирование (/INC) только файл file1.obj (другие подробности ­ – в MSDN).

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]