QPerformanceTimer

Every once in a while, I'd like to know how fast some piece of code runs. It may be that I'm not sure which of several implementations is the most efficient. Or perhaps I'm just curious.

The classical way to determine the processing time of a code block is by "profiling" it in the debugger. Alas, only a few developer environments have good support for this technique. Visual Studio is not one of them.

What remains is to throw in some timing functions in the code. Retrieve the system time at the entry point of the code block you're interested in, do it again at the exit point, and calculate the difference. It's not much work, but it starts to become quite annoying if you have to do it again and again.

I designed the C++ class QPerformanceTimer to avoid this annoyance. Whenever I'm interested in the processing time of some piece of code, I simply include a header, define two variables, and that's about all there is to it.

How to Use It

Here is how to proceed. Suppose you have some code you want to investigate, let's say a loop:

// interesting code to set up the loop...
...
for (int i = 0; i < BigNumber; ++i) DoSomethingTimeConsuming();
...
// more interesting code...

The first thing to do is to put the code in a block, if it isn't already, like so:

// interesting code to set up the loop...
...
{
   for (int i = 0; i < BigNumber; ++i) DoSomethingTimeConsuming();
}
...
// more interesting code...

Next, you define an int variable to receive the elapsed time in microseconds. Also, inside the block, you define a QPerformanceTimer variable. Its constructor takes a reference to the int. This is what you'll have:

#include "QPerformanceTimer.h"
...
// interesting code to set up the loop...
...
int nElapsedTime;
{
   QPerformanceTimer pt(nElapsedTime);

   for (int i = 0; i < BigNumber; ++i) DoSomethingTimeConsuming();
}
// at this point, nElapsedTime contains the time the code block
// has taken
...
// more interesting code...

Now, when the code block is completed, the elapsed time will be loaded into the int variable nElapsedTime. It can be examined in the debugger, it might be output with a trace statement, or it might be presented to the end user in a UI-element, or whatever.

How It Works

The QPerformanceTimer class is very simple. It has no member functions, just a constructor and a destructor. The constructor determines the starting time, and stores it in a member variable. The destructor retrieves the stop time, calculates the elapsed time, and stores it in the associated int variable. That's about all.

To get the time values, the "high-resolution performance counter" is used. This is a 64-bit hardware timer, which is initialized to zero at system start up and is incremented with a steady pace as long as the system is running. Windows offers two API-functions to query it:

  • QueryPerformanceCounter() simply gets you the current value of the counter in other words, the number of ticks since computer start-up;
  • QueryPerformanceFrequency() gets the counter frequency in counts per second.

My class uses these two functions. It's just a matter of multiplying the elapsed ticks with one million, and dividing by the frequency, to get the elapsed time in microseconds. To make it more user-friendly, the resulting value is converted to an int.

Consequently, the maximum time to be measured is slightly over half an hour, but this will be more than adequate for most situations. If an overflow occurrs, or the system doesn't support a performance timer, the associated int is loaded with -1.

The code for QPerformanceTimer is just in one small header file. Of course, its usage is limited to Windows (from Windows 95), but other than that it's quite portable. It can be used with MFC, ATL, or even in pure Windows API programs. It's written in VC++ 7.1 (.NET 2003), but I have no reason to believe that it can't be used in VC++ 6.0 or 7.0.

Demo

The demo is nothing special. It's a dialog-based MFC application that measures the time taken by some lengthy processes.

To make it mildly interesting, I used the opportunity to test the performance of two standard algorithms of the STL: std::sort() and std::stable_sort().

The first one is a general sort routine, and may mix up identical elements. The second one is, as its name implies, "stable," and preserves the order of identical elements. You typically use it to sort elements that have been sorted already by some other criterion. Generally, but not always, std::stable_sort() is less efficient than std::sort().

The demo exposes the difference between the two algorithms. It's also very instructive to compare a Debug build and a Release build of the demo. The difference in speed is huge.

For another use of QPerformanceTimer, albeit an older version, take a look at my article on Delaunay Triangulation.



Downloads

Comments

  • backlinks

    Posted by a High PR Backlink Pyramid r on 09/02/2012 12:09pm

    One important issue is that while you are searching for a education loan you may find that you will need a cosigner. There are many situations where this is correct because you should find that you do not use a past credit ranking so the lender will require that you've someone cosign the borrowed funds for you. Great post.

    Reply
  • patio furniture

    Posted by garrish27 on 07/21/2012 12:47am

    it is a beautiful website and interesting website.you can search a lot of information from this site.I think other blog proprietors should take this website as an model, very clean and great user genial style and design, let alone the content. Patio Furniture

    Reply
  • Superb

    Posted by Hacker2 on 08/16/2005 10:10pm

    Sometimes all you need is a quick simple tool. This is excellent. Thank you.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • The explosion in mobile devices and applications has generated a great deal of interest in APIs. Today's businesses are under increased pressure to make it easy to build apps, supply tools to help developers work more quickly, and deploy operational analytics so they can track users, developers, application performance, and more. Apigee Edge provides comprehensive API delivery tools and both operational and business-level analytics in an integrated platform. It is available as on-premise software or through …

  • As mobile devices have pushed their way into the enterprise, they have brought cloud apps along with them. This app explosion means account passwords are multiplying, which exposes corporate data and leads to help desk calls from frustrated users. This paper will discover how IT can improve user productivity, gain visibility and control over SaaS and mobile apps, and stop password sprawl. Download this white paper to learn: How you can leverage your existing AD to manage app access. Key capabilities to …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds