我的程序中的一些加載例程需要很長時間才能完成。我想要一個快速的小代碼來檢查函數執行的時間。小我的意思是「最好沒有第三方庫」。尋找基準代碼片段(C++)
也許像採取系統時間一樣簡單?
start = current_system_time()
load_something()
delta = current_system_time()-start
log_debug("load took "+delta)
編輯:目標操作系統中的問題是Windows操作系統。
我的程序中的一些加載例程需要很長時間才能完成。我想要一個快速的小代碼來檢查函數執行的時間。小我的意思是「最好沒有第三方庫」。尋找基準代碼片段(C++)
也許像採取系統時間一樣簡單?
start = current_system_time()
load_something()
delta = current_system_time()-start
log_debug("load took "+delta)
編輯:目標操作系統中的問題是Windows操作系統。
你的回答:是的
警告:這將multihtreaded代碼或多核機器不工作,你需要一個強大的牆時鐘定時器。 所以我建議你使用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)
這是一種快速和骯髒的方式來計時一段C/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);
這應該在現代的Linux系統給1-2μs分辨率(您使用的是什麼操作系統?),這意味着它不適合學習很多項目採取<10μs。但是,你似乎並不處於這種情況。
更新:基於特定的操作系統... Windows implementation of gettimeofday()
#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();
}
我使用一個類此,它旨在衡量執行所花費的時間一個函數並將其寫入一個uth-16le文本文件中(我需要更新它以使用我爲此創建的新類,但是nm)。
在函數頂部創建一個新實例,例如, 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);
}
我在sweet.hpp圖書館benchmark.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());
這不會得到任何答案,因爲「是」太短而無法發佈。 – 2009-01-27 12:15:22
我一直希望得到一個「是」,然後是「但是更清潔/更好的主意是......」 – Mizipzor 2009-01-27 12:25:15