Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations bkrike on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How To Perform Timing Functions

How To

How To Perform Timing Functions

by  Glenn9999  Posted    (Edited  )
Inevitably, part of a program will involve timing something. This involves either wanting to find out how long something takes to run, or some other function that involves the accumulation of time (synchronization of a TrackBar on your form to a music player, or a stopwatch, for example). This will describe the methods accessible under Windows to do such things.

What NOT to do
What not to do is to use the system time formatting functions like GetSystemTime. The API formats the computer time into something that is human readable, and will often take a number of CPU cycles. This is NOT what you really want and will cause problems.

thread209-1545808 , see post #9.

The Multi-Media Timer
The easiest thing to do to get a rough time of something is to access the multimedia timer. To do this, you call timeGetTime of WINMM.DLL before the code you want to time and then after the code you want to time. The difference of the two numbers represents the elapsed time. This will generally work on any system, so it is useful.

[link http://msdn.microsoft.com/en-us/library/ms713418.aspx]timeGetTime[/link]

Code:
{$APPTYPE CONSOLE}
program prog1; uses windows;
  { demonstration of the multi-media timer }

  function timeGetTime: DWord; stdcall; external 'winmm.dll' name 'timeGetTime';

  var
    InitialTime, EndTime: DWord;

    x, y: integer;
  begin
    for y := 1 to 10 do
      begin
        InitialTime := timeGetTime;
        for x := 1 to 100 do
          sleep(10);
        EndTime := timeGetTime;
        writeln(EndTime - InitialTime, ' ms.');
      end;
    write('Press ENTER.');
    readln;
  end.

The Hi-Res Timer
Some systems support a high-resolution timer. This can be useful if you need more than millisecond resolution. To access it within Windows, you use two functions out of KERNEL32.DLL.

[link http://msdn.microsoft.com/en-us/library/ms644905.aspx]QueryPerformanceFrequency[/link]
[link http://msdn.microsoft.com/en-us/library/ms644904(VS.85).aspx]QueryPerformanceCounter[/link]

QueryPerformanceFrequency provides a number of units per second for the system. I get the feeling that this number is directly proportional to the number of instructions per second the CPU can perform, given my tests on a number of systems. Microsoft doesn't specifically identify where this number comes from, so I just call it "units".

Then QueryPerformanceCounter is used as timeGetTime to measure the duration of whatever it is you want to time. To get seconds, you divide by whatever number QueryPerformanceFrequency returns.

Code:
{$APPTYPE CONSOLE}
program prog2; uses windows;
  { demonstration of the NT high-res timer }

  type
    Int64 = Comp;
    
  function QueryPerformanceFrequency(var lpFrequency: Int64): boolean;
        stdcall; external 'kernel32.dll' name 'QueryPerformanceFrequency';
  function QueryPerformanceCounter(var lpPerformanceCount: Int64): boolean;
        stdcall; external 'kernel32.dll' name 'QueryPerformanceCounter';
  var
    x, y: integer;
    lFreq: Int64;
    InitialF, FinalF: Int64;
  begin
    if QueryPerformanceFrequency(lFreq) then
      writeln('Hi-Res Timer Supported.')
    else
      // also can exit out here.
      writeln('Hi-Res Timer Not Supported.');
    writeln('Frequency: ', lFreq:0:0, ' units per second.');
    writeln('Time Resolution: ', (1 / lFreq):0:16, ' seconds.');
    for y := 1 to 10 do
      begin
        QueryPerformanceCounter(InitialF);
        for x := 1 to 100 do
          sleep(10);
        QueryPerformanceCounter(FinalF);
        writeln(' Duration: ', (FinalF - InitialF):0:0);
        // if you save this to variable, it needs to be Extended
        writeln( ((FinalF-InitialF) / lFreq):0:16, ' seconds.');
      end;
    write('Press ENTER.');
    readln;

  end.
Register to rate this FAQ  : BAD 1 2 3 4 5 6 7 8 9 10 GOOD
Please Note: 1 is Bad, 10 is Good :-)

Part and Inventory Search

Back
Top