C++: time.h

De Wiki de Calcul Québec
Aller à : Navigation, rechercher
Cette page est une traduction de la page C++ : time.h et la traduction est complétée à 100 % et à jour.

Autres langues :anglais 100% • ‎français 100%

C++ : a performance analysis tool based on time.h

You can use the functions defined in the standard header file <time.h> to construct a simple and user-friendly performance analysis tool. The chronometer defined below can be very useful for optimizing your program. It allows you to measure the time spent in the chosen code blocks.


File : chronometer.cpp
#include <list>
#include <string>
#include <iostream>
#include <time.h>
 
using namespace std;
 
class Chronometer
{
public:
    // ----------------------------------
    // instance methods
    // ----------------------------------
 
    // constructor
    Chronometer(const string& name);
 
    // destructor
    ~Chronometer();
 
    // start measuring time
    inline void Start();
 
    // stop measuring time
    inline void Stop();
 
    // get elapsed time (in seconds)
    double ElapsedTime() const;
 
 
    // ----------------------------------
    // class methods
    // ----------------------------------
 
    // total elapsed time (in seconds) for all chronometers
    static double TotalElapsedTime();
 
    // write report on standard output
    static void Report();
 
private:
    // private data
    clock_t     begin;
    clock_t     total;
    string      name;
    static list<Chronometer*> chronometerList;
};
 
 
// ----------------------------------
// static member initialization
// ----------------------------------
 
list<Chronometer*> Chronometer::chronometerList;
 
 
// ----------------------------------
// method implementations
// ----------------------------------
 
Chronometer::Chronometer(const string& name) : total(0), name(name)
{
    chronometerList.push_back(this);
}
 
Chronometer::~Chronometer()
{
    chronometerList.remove(this);
}
 
void Chronometer::Start()
{
    begin = clock();
}
 
void Chronometer::Stop()
{
    total += clock() - begin;
}
 
double Chronometer::ElapsedTime() const
{
    return (double) total / CLOCKS_PER_SEC;
}
 
double Chronometer::TotalElapsedTime()
{
    double total = 0;
 
    for (list<Chronometer*>::const_iterator i = chronometerList.begin();
         i != chronometerList.end(); ++i)
    {
        total += (*i)->total;
    }
 
    return (double) total / CLOCKS_PER_SEC;
}
 
void Chronometer::Report()
{
    cout << "--------------------------------" << endl;
 
    for (list<Chronometer*>::const_iterator i = chronometerList.begin();
         i != chronometerList.end(); ++i)
    {
        cout << "chronometer " << (*i)->name << ": "
             << (*i)->ElapsedTime()
             << " seconds" << endl;
    }
 
    cout << "--------------------------------" << endl
         << "total = " << TotalElapsedTime()   << endl
         << "--------------------------------" << endl;
}


The macros below allow you to activate the performance analysis only when the compiler directive ACTIVATE_CHRONOMETER is defined (you need to add the option -DACTIVATE_CHRONOMETER to the compiler arguments).


File : chronometer.h
#ifdef ACTIVATE_CHRONOMETER
 
#define START_CHRONOMETER(name) static Chronometer name(#name); name.Start();
#define STOP_CHRONOMETER(name) name.Stop();
#define CHRONOMETER_REPORT() Chronometer::Report();
 
#else
 
#define START_CHRONOMETER(name)
#define STOP_CHRONOMETER(name)
#define CHRONOMETER_REPORT()
 
#endif


Here's an example of its use:


File : chronometer_example.cpp
void function1()
{
    START_CHRONOMETER(function1)
    ...
    STOP_CHRONOMETER(function1)
}
 
void function2()
{
    START_CHRONOMETER(function2)
    ...
    STOP_CHRONOMETER(function2)
}
 
void function3()
{
    START_CHRONOMETER(function3_outer)
    ...
    START_CHRONOMETER(function3_inner)
    ...
    STOP_CHRONOMETER(function3_inner)
    ...
    STOP_CHRONOMETER(function3_outer)
}
 
int main()
{
    for (int i = 1; i < 1000000; ++i)
    {
        function1();
        function2();
        function3();
    }
    CHRONOMETER_REPORT()
}


Output:

--------------------------------
chronometer function1: 0.62 seconds
chronometer function2: 0.67 seconds
chronometer function3_outer: 2.06 seconds
chronometer function3_inner: 0.66 seconds
--------------------------------
total = 4.01
--------------------------------

Note that because of the static declaration of the Chronometer objects, this tool cannot be used in recursive functions or which might be called simultaneously by several threads (i.e. it isn't thread-safe). This approach is nevertheless very light-weight because it avoids creating a new Chronometer object on the stack each time that the code block in question is executed.

Remember that measuring the time requires time itself. The results will be more reliable if the code block being targeted by a chronometer is fairly lengthy in comparison with the measurement operation.

Outils personnels
Espaces de noms

Variantes
Actions
Navigation
Ressources de Calcul Québec
Outils
Partager