Download Test Project
Timers serve many purposes for computer programs. They can be used to track time, schedule events, and as a stopwatch to measure how long an activity takes.
However, when it comes to measuring how long code takes to run, many traditional timers lack the resolution to measure fractions of a second in a meaningful way.
For these cases, Windows provides the QueryPerformanceCounter() API function, which returns a very high-resolution value that can be used to time short intervals.
The CHRTimer Class
Listing 1 shows my CHRTimer class. This class is quite simple and exists entirely within a header file (no CPP file).
The class relies on the QueryPerformanceCounter() API function to measure short intervals of time. Internally, it has two LARGE_INTEGER member variables, m_liStart and m_liStop.
The Start() method stores the current counter value in m_liStart, and the Stop() method stores the current value in m_liStop. After calling both methods, an application can call GetElapsed() to get the number of counts between the start and stop times.
The GetElapsedAsSeconds() method is also provided. This method uses the same value returned by GetElapsed() and then divides that value by the number returned by the QueryPerformanceFrequency() API function. This function returns the number of counts that occur per second on the current system.
Listing 1: The CHRTimer Class
m_liStart.QuadPart = m_liStop.QuadPart = 0;
// Starts the timer
// Stops the timer
// Returns the counter at the last Start()
// Returns the counter at the last Stop()
// Returns the interval between the last Start() and Stop()
return (m_liStop.QuadPart - m_liStart.QuadPart);
// Returns the interval between the last Start() and Stop() in seconds
return ((double)GetElapsed() / (double)liFrequency.QuadPart);
Using the Class
As described previously, to use this class simply call the Start() method, then perform the activity you want to time, and then call the Stop() method. You can then call the GetElapsed() and/or GetElapsedAsSeconds() methods to get the timer measurement.
Listing 2 demonstrates this sequence.
Listing 2: Using the CHRTimer Class
// Create timer
// Start the timer
// Do some processing
// Stop the timer
// Get time elapsed
Words of Warning
I should point out the while these routines can distinguish between very small time intervals, they are not accurate time keepers. That is, they are very good at detecting tiny variations in lengths of time, but if they report something took exactly one and a half seconds, that information is less reliable.
One reason for this is because not all computers provide the same hardware for QueryPerformanceCounter() to work with. The timer used can vary widely between systems. The GetPerformanceFrequency() function helps normalize for different hardware but variations between systems may still occur.
I've also read reports that these timer calculations can, in rare instances, vary the pace or even go backwards for short periods. And finally, the documentation is not very clear about when the timer start. Presumably, it could wrap around at some point. Although, being a 64-bit value, that's not going to happen very often.
The bottom line is that this code is more meaningful when comparing different intervals on the same system. And it's always a good idea to get multiple readings before making big changes to tweak your code.
With my warnings out of the way, I've found this to be a very useful class capable of measuring very small time intervals. It works really well for measuring the time it takes for some block of code to execute. And it's very simple to implement and use.
Use of this article and any related source code or other files is governed
by the terms and conditions of