Поиск фрагмента кода для сравнения (С++)
Некоторые загрузочные процедуры в моей программе занимают много времени. Я хочу быстрый небольшой фрагмент для проверки того, как долго выполнялась функция для выполнения. Маленьким я имею в виду "желательно без сторонних библиотек".
Может быть, что-то так же просто, как взять системное время?
start = current_system_time()
load_something()
delta = current_system_time()-start
log_debug("load took "+delta)
Изменить: Целевая ОС - Windows.
Ответы
Ответ 1
Ваш ответ: Да
Предостережение. НЕ РАБОТАЕТ работать в многостраничном коде или нескольких основных машинах, вам нужен надежный таймер настенных часов.
Поэтому я рекомендую вам использовать omp wallclock. OMP включен в VC и GCC, а большинство компиляторов и его стандарт вам не нужно беспокоиться об исчезновении
#include <omp.h>
// Starting the time measurement
double start = omp_get_wtime();
// Computations to be measured
...
// Measuring the elapsed time
double end = omp_get_wtime();
// Time calculation (in seconds)
Ответ 2
#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
namespace win32 {
#include <windows.h>
}
class timer
{
win32::LARGE_INTEGER start_time_;
public:
timer() { QueryPerformanceCounter( &start_time_ ); }
void restart() { QueryPerformanceCounter( &start_time_ ); }
double elapsed() const
{
win32::LARGE_INTEGER end_time, frequency;
QueryPerformanceCounter( &end_time );
QueryPerformanceFrequency( &frequency );
return double( end_time.QuadPart - start_time_.QuadPart )
/ frequency.QuadPart;
}
};
#else
#include <ctime>
class timer
{
clock_t _start_time;
public:
timer() { _start_time = clock(); }
void restart() { _start_time = clock(); }
double elapsed() const
{
return double(clock() - _start_time) / CLOCKS_PER_SEC;
}
};
#endif
template< typename Func >
double measure_time( Func f )
{
timer t;
f();
return t.elapsed();
}
Ответ 3
Это быстрый и грязный способ блокировать код кода C/С++. Вам нужно #include <sys/time.h>
, который должен быть стандартным заголовком...
struct timeval start, end;
gettimeofday(&start, NULL);
// benchmark code
gettimeofday(&end, NULL);
long long time = (end.tv_sec * (unsigned int)1e6 + end.tv_usec) -
(start.tv_sec * (unsigned int)1e6 + start.tv_usec);
Это должно дать разрешение в 1-2 мксека на современных Linux-системах (какая ОС вы используете?), что означает, что она не очень хорошо подходит для многого для приема элементов с < 10 мкс. Однако, похоже, вы не находитесь в этой ситуации.
Обновление: На основе указанной ОС... Реализация Windows gettimeofday()
Ответ 4
Я использую для этого класс, который предназначен для измерения времени выполнения функции и записи ее в текстовый файл uth-16le (мне нужно обновить это, чтобы использовать новый класс, созданный для этого... но нм).
Создайте новый экземпляр в верхней части функции, например. jProfiler (L "myFunction" ), а очистка в конце функции сделает все остальное, если вы хотите быть уверенным, что новый и удалить его самостоятельно. Его немного переборщик для небольшого теста, но может помочь:
// start header
/* jProfiler class by Semi Essessi
*
* (class description goes here)
*
*/
#ifndef __JPROFILER_H
#define __JPROFILER_H
#include <stdio.h>
#include <windows.h>
class jProfiler
{
private:
wchar_t* str;
LARGE_INTEGER start;
LARGE_INTEGER tps;
LARGE_INTEGER buf;
static FILE* f;
static int instCount;
static void Initialise();
static void Shutdown();
public:
jProfiler(const wchar_t* msg);
~jProfiler();
};
#endif
// - end header
/* jProfiler class by Semi Essessi
*
* (class description goes here)
*
*/
#include "jProfiler.h"
#include <windows.h>
FILE* jProfiler::f = 0;
int jProfiler::instCount = 0;
jProfiler::jProfiler(const wchar_t* msg)
{
// constructor code for menuVar
int i = (int)wcslen(msg)+1;
str = new wchar_t[i];
memcpy(str, msg, sizeof(wchar_t)*i);
str[i-1] = 0;
QueryPerformanceFrequency(&tps);
QueryPerformanceCounter(&start);
instCount++;
Initialise();
}
jProfiler::~jProfiler()
{
// destructor code for menuVar
QueryPerformanceCounter(&buf);
// work out change in time
double dt=((float)buf.QuadPart - (float)start.QuadPart)/(float)tps.QuadPart;
fwprintf(f, L"%s : %.20f\r\n", str, dt);
if(str) delete[] str;
instCount--;
Shutdown();
}
void jProfiler::Initialise()
{
if(!f)
{
f = _wfopen(L"profilerlog.txt", L"wb");
unsigned short a = 0xFEFF;
fwrite(&a, sizeof(unsigned short), 1, f);
}
}
void jProfiler::Shutdown()
{
if(instCount==0) if(f) fclose(f);
}
Ответ 5
У меня есть заголовок benchmark.hpp в моей библиотеке sweet.hpp. Он имеет два инструмента сравнения. Первый - это простой ручной старт-секундомер
Bench b;
...
b.stop();
b.milli(); // returns an uint with passed millisec. Also has sec and micro sec
Другой - немного сложнее. Вы пишете функции или блокируете такие утверждения.
void myFunc() {
BENCH(someName);
...
}
И в конце звоните sweet::Benchmark::printResults();
, чтобы тратить время и количество напечатанных звонков.
Изменить:
Я добавил функцию, чтобы вы могли ее вызвать следующим образом.
double c = BENCHMARK_CNT(25, yourFunctionCallHere());