Mega Code Archive

 
Categories / Delphi / Forms
 

How To Perform Timing Functions

Title: How To Perform Timing Functions 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: How to return time value to thousandths of a second? , 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. timeGetTime 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. QueryPerformanceFrequency QueryPerformanceCounter 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.