Тестирование производительности участка кода

Тестирование производительности участка кода. Оценка производительности алгоритма

Иногда бывает необходимость протестировать алгоритм или часть кода, чтоб узнать "не здесь ли тормозит?". А использование профайлера слишком монструозно или не практично. Тогда можно замерить производительность участка кода, прямо в коде. Для этого есть много методов, и все они не без погрешностей.
[spoiler]
Чем могут быть вызваны погрешности?
Операционные системы многозадачны, и чаще имеют архитектору вытесняющей многозадачности по приоритетам. Система может отдать процессорное время другому процессу, а не нашему тестируемому. Также приложение вовремя вызова системных сервисов может находится в режиме ядра, и это тоже влияет на результат замера.
Также сам метод имеет определенную точность, и погрешность.=)

Поэтому для большой точности замера, поставьте приоритет реального времени Вашему процессу, но это может решить лишь проблему с вытеснением другим процессом. Для решение проблем с режимами нужно использовать другие методы, такие например как GetSystemTime для Windows, но у нее большие погрешности во времени замера.

Следует, также "прогнать" замеры несколько раз, взять средний результат, так, как погрешности все равно будут и от них никуда не деться.=)

И так самими методы:
/*http://esate.ru, Flashhell*/


#include <vector>   // STL массив - vector
#include <iostream>  // ввод, вывод
#include <algorithm> // для функции перемешивания random_shuffle, но там есть еще много вкусностей=)

using namespace std;
// для работы подсчета тактов Windows  - 1) МЕТОД
#include <intrin.h>      
#pragma intrinsic(__rdtsc)
//------------------------------------------------
// стандартные для C функции и структуры работы со временем - 2) МЕТОД
#include <time.h> 
//------------------------------------------------
// 3) МЕТОД и 4 МЕТОД
#include <windows.h>
//------------------------------------------------

// тестируемый алгоритм, если можно его так назвать =)
void test_algorithm();


//! Метод подсчета тактов процессора(Windows)   - 1) МЕТОД
unsigned __int64 tick()
{
  return (__rdtsc());
}

//! ifdef макрос определяющий OS LInux на gcc   - 1) МЕТОД
#ifdef __linux__
//! Метод подсчета тактов процессора(Linux)
static inline unsigned long long int tick() 
{
  unsigned long long int d;
  __asm__ __volatile__ ("rdtsc" : "=A" (d) );
  return d;
}
#endif

int main()
{
  // 1) Метод
  unsigned long long int a = 0;
  unsigned long long int b = 0;
  a=tick();
  test_algorithm();
  b=tick();
  cout<<"1) Method "<<b-a<<"\n";

  // 2) Метод
  clock_t time;
  time = clock();
  test_algorithm();
  time = clock() - time;
  cout <<"2) Method "<<time<<"\n"; 
  cout <<"2) Method time in seconds "<<(double)time / CLOCKS_PER_SEC<<"\n"; 

  // 3) Метод
  double start = GetTickCount();
  test_algorithm();
  double finish = GetTickCount();
  cout <<"3) Method  "<<finish - start<<"\n";
  cout <<"3) Method time in seconds "<<(double)(finish - start) / CLOCKS_PER_SEC<<"\n"; //CLOCKS_PER_SEC объявлен в time.h

  // 4) Метод
  LARGE_INTEGER freq;
  QueryPerformanceFrequency(&freq);

  LARGE_INTEGER time1;
  QueryPerformanceCounter(&time1);

  test_algorithm();

  LARGE_INTEGER time2;
  QueryPerformanceCounter(&time2);
  time2.QuadPart -= time1.QuadPart;
  double span = (double) time2.QuadPart / freq.QuadPart;
  cout <<"4) Method time in seconds "<<span<<"\n";


  

  return 0;
}

//! Тестируемый алгоритм, сейчас представляет лишь цикл забивки вектора и его перемешивание
void test_algorithm()
{
  vector <int> vec;
  int i = 0;

  while(i < 100000)
  {
    vec.push_back(i);
    i++;
  }

  random_shuffle(vec.begin(), vec.end());
}



Сразу прошу не обижаться, на большое количество комментов в коде, я посчитал, что так лучше ИМХО)))

PS
Все представленные здесь методы так или иначе завязаны на тактах процессора.
Если Вам нужно протестить много кода, лучше задумать об использовании профайлера, к примеру codeanalyst

СКАЧАТЬ проект


Полезные ссылки:
1 Метод
2 Метод, про time.h
Про архитектуру и режимы
Про GNU профайлер gprof
0       4469        09.05.2012        2

0  
15.01.2015 14:00:21
Хорошо было бы увидеть скрин с работой программы, что бы увидеть разницу в этих методах)
0  
15.01.2015 18:20:28
К публикации приложена ссылка на исходные коды проекта (в конце статьи)
^