In this article, you will see a C# class which can provide exact time measurement in applications.
Introduction
In some applications, exact time measurement methods are very important. The often used Windows API method GetTickCount()
retrieves the number of milliseconds that have elapsed since the system was started, but the GetTickCount()
function only achieves resolutions of 1ms and on the other side, they are very imprecise.
So, for exact time measurement, we should find another method.
High resolution timing is supported in Win32 by the QueryPerformanceCounter()
and QueryPerformanceFrequency()
API methods. This timer functions have much better resolution than the "standard" millisecond-based timer calls, like the GetTickCount()
method. On the other side, there is also a little bit overhead when calling this "unmanaged" API methods from C#, but it's better than using the very imprecise GetTickCount()
API function.
The first call, QueryPerformanceCounter()
, queries the actual value of the high-resolution performance counter at any point. The second function, QueryPerformanceFrequency()
, will return the number of counts per second that the high-resolution counter performs. To retrieve the elapsed time of a code section, you have to get the actual value of the high-resolution performance counter immediately before and immediately after the section of code to be timed. The difference of these values would indicate the counts that elapsed while the code executed.
The elapsed time can be computed then, by dividing this difference by the number of counts per second that the high-resolution counter performs (the frequency of the high-resolution timer).
duration = (stop - start) / frequency
For more information about QueryPerformanceCounter and QueryPerformanceFrequency, read the documentation on MSDN.
The Code
The following class implements the functionality of the QueryPerformanceCounter()
and QueryPerformanceFrequency()
API methods.
using System;
using System.Runtime.InteropServices;
using System.ComponentModel;
using System.Threading;
namespace Win32
{
internal class HiPerfTimer
{
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceCounter(
out long lpPerformanceCount);
[DllImport("Kernel32.dll")]
private static extern bool QueryPerformanceFrequency(
out long lpFrequency);
private long startTime, stopTime;
private long freq;
public HiPerfTimer()
{
startTime = 0;
stopTime = 0;
if (QueryPerformanceFrequency(out freq) == false)
{
throw new Win32Exception();
}
}
public void Start()
{
Thread.Sleep(0);
QueryPerformanceCounter(out startTime);
}
public void Stop()
{
QueryPerformanceCounter(out stopTime);
}
public double Duration
{
get
{
return (double)(stopTime - startTime) / (double) freq;
}
}
}
}
This class is very simple to use. Just create an instance of HiPerfTimer
, call Start()
to start timing and call Stop()
to stop timing. To retrieve the elapsed time, just call the Duration()
function and you will get the elapsed time.
The following sample should explain that:
HiPerfTimer pt = new HiPerfTimer();
pt.Start();
Console.WriteLine("Test\n");
pt.Stop();
Console.WriteLine("Duration: {0} sec\n",
pt.Duration);
The following image shows the output of this sample on my system:
History
- 26th July, 2002 - Posted (first version)
- 29th August, 2002 - Added some code for more robustness of the class
Bugs and Comments
If you have any comments or find some bugs, I would love to hear about it and make it better.