In the process of testing STL I have wanted to know how fast various loops are. After some mucking around doing things the hard way, I made a simple class that will time any "batch" of code, by simply using a single line. For example, to time "something" I might do this:
The interesting thing here is that the entire work is done in the timer class constructor and destructor. The constructor makes a note of the current time, and echoes the "start" message.
The destructor makes a note of the (new) current time, subtracts the finish from the start, and displays the interval.
It is adapted to use the high-performance timer under Windows, and the gettimeofday under Unix.
You can nest calls (see example program) so you can time smaller bits of code while still timer the larger overall picture.
The purpose of the braces is to "scope" the timer class so that when it hits the closing brace it goes out of scope and the destructor is called.
If you simply want to time an entire function, this is not necessary as the destructor is called when the function exits.
eg.
You could make it fancier - eg. make the displaying of the time optional, however this is a good starting point.
Example Output
{
timer t ("testing something");
something ();
}
The interesting thing here is that the entire work is done in the timer class constructor and destructor. The constructor makes a note of the current time, and echoes the "start" message.
The destructor makes a note of the (new) current time, subtracts the finish from the start, and displays the interval.
It is adapted to use the high-performance timer under Windows, and the gettimeofday under Unix.
You can nest calls (see example program) so you can time smaller bits of code while still timer the larger overall picture.
The purpose of the braces is to "scope" the timer class so that when it hits the closing brace it goes out of scope and the destructor is called.
If you simply want to time an entire function, this is not necessary as the destructor is called when the function exits.
eg.
void myfunction (void)
{
timer t ("myfunction");
// do something lengthy here
} // end of myfunction - time elapsed will be displayed
You could make it fancier - eg. make the displaying of the time optional, however this is a good starting point.
// disable warnings about long names
#ifdef WIN32
#pragma warning( disable : 4786)
#endif
#include <string>
#include <iostream>
#include <iomanip>
#include <deque>
#include <list>
#include <vector>
#ifdef WIN32
#include <windows.h> // for QueryPerformanceCounter
#else
#include <sys/time.h> // for gettimeofday
#endif
using namespace std;
class timer
{
#ifdef WIN32
LARGE_INTEGER start;
LONGLONG iCounterFrequency;
#else
long long start;
#endif
const string sReason;
public:
// constructor remembers time it was constructed
timer (const string s) : sReason (s)
{
#ifdef WIN32
LARGE_INTEGER large_int_frequency;
QueryPerformanceFrequency (&large_int_frequency);
iCounterFrequency = large_int_frequency.QuadPart;
QueryPerformanceCounter (&start);
#else
struct timeval t;
gettimeofday( &t, NULL );
start = (t.tv_sec * 1000000L) + t.tv_usec;
#endif
cout << "Start : " << setw (25) << left << sReason << endl;
};
// destructor gets current time, displays difference
~timer ()
{
#ifdef WIN32
LARGE_INTEGER finish;
LONGLONG iTimeTaken;
QueryPerformanceCounter (&finish);
iTimeTaken = finish.QuadPart - start.QuadPart;
double fTime = ((double) iTimeTaken) /
((double) iCounterFrequency);
#else
struct timeval t;
gettimeofday( &t, NULL );
long long finish = (t.tv_sec * 1000000L) + t.tv_usec;
double fTime = (finish - start) / 1000000.0;
#endif
cout << "Time taken: " << setw (25) << left << sReason << " = "
<< fixed << fTime << " seconds." << endl;
}
}; // end of class timer
#define LOOPS 50000
int main (void)
{
timer all_things ("overall");
{
timer t ("testing vector");
vector<string> v;
for (int i = 1; i < LOOPS; i++)
v.push_back ("hi there");
}
{
timer t ("testing list");
list<string> L;
for (int i = 1; i < LOOPS; i++)
L.push_back ("hi there");
}
{
timer t ("testing deque");
deque<string> d;
for (int i = 1; i < LOOPS; i++)
d.push_back ("hi there");
}
return 0;
} // end of main
Example Output
Start : overall
Start : testing vector
Time taken: testing vector = 0.094685 seconds.
Start : testing list
Time taken: testing list = 0.065218 seconds.
Start : testing deque
Time taken: testing deque = 0.045103 seconds.
Time taken: overall = 0.206196 seconds.