c++ - tag - structured data guida




Alla ricerca di snippet di codice benchmarking(c++) (4)

Ho un'intestazione benchmark.hpp nella mia libreria sweet.hpp . Ha due strumenti di riferimento. Il primo è un semplice strumento manuale per l'arresto della partenza

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

L'altro è un po 'più sofisticato. Si scrivono funzioni o istruzioni di blocco come questa.

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

E alla fine chiama sweet::Benchmark::printResults(); per avere il tempo trascorso e il numero di chiamate stampate.

Modifica: ho aggiunto una funzione così puoi chiamarla così.

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

Alcune routine di caricamento nel mio programma impiegano molto tempo per essere completate. Voglio un rapido piccolo frammento per verificare quanto tempo è necessario eseguire una funzione. Per piccolo intendo "preferibilmente senza librerie di terze parti".

Forse qualcosa di semplice come prendere il tempo del sistema?

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

Modifica: il SO di destinazione in questione è Windows.


Io uso una classe per questo, è stato progettato per misurare il tempo impiegato per eseguire una funzione e scriverlo in un file di testo uth-16le (ho bisogno di aggiornarlo per usare una nuova classe che ho creato per questo ... ma nm).

Crea una nuova istanza nella parte superiore di una funzione, ad esempio jProfiler (L "myFunction") e la pulizia alla fine della funzione farà il resto, se vuoi essere sicuro di nuovo ed eliminarlo tu stesso. È un po 'eccessivo per un piccolo test, ma potrebbe aiutare:

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

Questo è un modo veloce e sporco di temporizzare un blocco di codice C / C ++. È necessario #include <sys/time.h> , che dovrebbe essere un'intestazione standard ...

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

Questo dovrebbe dare una risoluzione di 1-2μs sui moderni sistemi Linux (quale sistema operativo stai usando?), Il che significa che non è adatto per imparare molto per gli articoli che richiedono <10μs. Tuttavia, non ti sembra di essere in quella situazione.

Aggiornamento: basato sul sistema operativo specificato ... Implementazione di Windows di 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();
}




benchmarking