2009-01-27 10 views
24

Niektóre procedury ładowania w moim programie trwa długo. Chcę krótki mały fragment służący do sprawdzenia, jak długo funkcja była wykonywana. Przez małe mam na myśli "najlepiej bez bibliotek zewnętrznych".Szukasz kodu porównawczego kodu (C++)

Może coś równie prostego jak zabranie czasu systemowego?

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

Edit: docelowa OS w pytaniu jest Windows.

+0

Nie otrzymamy żadnych odpowiedzi, ponieważ "tak" jest zbyt krótkie, aby opublikować. –

+2

Miałem nadzieję na "tak", po którym następuje "ale o wiele czystszy/lepszy pomysł to ..." – Mizipzor

+0

Na jakim systemie operacyjnym jesteś? –

Odpowiedz

20

Twoja odpowiedź: Tak

Zastrzeżenie: To NIE praca w kodzie multihtreaded lub wielu maszynach podstawowych, trzeba mieć solidną ścianę zegar zegarowy. Polecam więc użyć zegarka omp. OMP jest dołączony VC i GCC oraz większości kompilatorów i jej standard nie trzeba się martwić o znikają

#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) 
+4

Upewnij się, że link do -lgomp –

5

To szybki i brudny sposób na czas blokowania kodu C/C++. Trzeba #include <sys/time.h>, co powinno być standardem nagłówek ...

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); 

To powinno dać 1-2μs uchwałę o nowoczesnych systemach Linux (co OS używasz?), Co oznacza, że ​​nie jest dobrze nadaje się do nauki dużo za przedmioty z < 10μs. Jednak wydaje się, że nie jesteś w takiej sytuacji.

Aktualizacja: w oparciu o określone OS ... 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

używam klasę do tego, jej przeznaczony do pomiaru czasu potrzebnego do wykonania funkcję i zapisz ją do pliku tekstowego uth-16le (muszę to zaktualizować, aby użyć nowej klasy stworzonej dla tego ... ale nm).

Utwórz nową instancję u góry funkcji, np. jProfiler (L "myFunction") i czyszczenie na końcu funkcji zrobi resztę, jeśli chcesz się upewnić, że jest nowa i usunąć ją samemu. Jest to trochę overkill dla małej próbie, ale może pomóc:

// 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

Mam benchmark.hpp nagłówek w moim sweet.hpp bibliotece. Posiada dwa narzędzia do testów porównawczych. Pierwszym z nich jest prosty, ręczny czas oczekiwania na zatrzymanie startu.

Bench b; 
... 
b.stop(); 
b.milli(); // returns an uint with passed millisec. Also has sec and micro sec 

Drugi jest nieco bardziej wyrafinowany. Piszesz funkcje lub blokujesz instrukcje w ten sposób.

void myFunc() { 
    BENCH(someName); 
    ... 
} 

A w zaproszeniu końcowego sweet::Benchmark::printResults(); mieć poświęcić czas i liczbę połączeń drukowanych.

Edytuj: Dodałem funkcję, dzięki czemu możesz ją tak nazwać.

double c = BENCHMARK_CNT(25, yourFunctionCallHere());