2009-01-27 84 views
24

我的程序中的一些加載例程需要很長時間才能完成。我想要一個快速的小代碼來檢查函數執行的時間。小我的意思是「最好沒有第三方庫」。尋找基準代碼片段(C++)

也許像採取系統時間一樣簡單?

start = current_system_time() 
load_something() 
delta = current_system_time()-start 
log_debug("load took "+delta) 

編輯:目標操作系統中的問題是Windows操作系統。

+0

這不會得到任何答案,因爲「是」太短而無法發佈。 – 2009-01-27 12:15:22

+2

我一直希望得到一個「是」,然後是「但是更清潔/更好的主意是......」 – Mizipzor 2009-01-27 12:25:15

回答

20

你的回答:是的

警告:這將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) 
5

這是一種快速和骯髒的方式來計時一段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()

14
#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(); 
} 
1

我使用一個類此,它旨在衡量執行所花費的時間一個函數並將其寫入一個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); 
} 
1

我在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());