22

I would like to know how to calculate the time consumed for a function in Delphi.

Then I wanted to show the used time and compare it with another function or component so as to know the faster function.

Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
Hidden
  • 3,598
  • 4
  • 34
  • 57
  • 4
    Possible duplicate, [`Calculating the speed of routines?`](http://stackoverflow.com/q/6030586/576719). – LU RD Jun 07 '13 at 13:04
  • 3
    Definitely a duplicate, another candidate: [Delphi - How to make timer in milliseconds or nanoseconds with start/stop functions?](http://stackoverflow.com/questions/14834534/delphi-how-to-make-timer-in-milliseconds-or-nanoseconds-with-start-stop-functi) – Glenn1234 Jun 07 '13 at 15:39

4 Answers4

70

You can use TStopwatch from the System.Diagnostics unit to measure elapsed time using the system's high-resolution performance counter.

var
  Stopwatch: TStopwatch;
  Elapsed: TTimeSpan;
....
Stopwatch := TStopwatch.StartNew;
DoSomething;
Elapsed := Stopwatch.Elapsed;

To read a time value in seconds, say, from a time span, do this:

var
  Seconds: Double;
....
Seconds := Elapsed.TotalSeconds;
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
22

You can use the QueryPerformanceCounter and QueryPerformanceFrequency functions:

var
  c1, c2, f: Int64;
begin
  QueryPerformanceFrequency(f);
  QueryPerformanceCounter(c1);
  DoSomething;
  QueryPerformanceCounter(c2);

  // Now (c2-c1)/f is the duration in secs of DoSomething
Andreas Rejbrand
  • 105,602
  • 8
  • 282
  • 384
  • Secs or ms? Because i got a huuuuge number. – Hidden Jun 07 '13 at 12:45
  • Mh maybe i did something wrong? .. Ergebnis := c2-c1; Label2.Caption := 'Benötigte Zeit: ' + IntToStr(Ergebnis); And i got this ... Look at "Benötigte Zeit" http://db.tt/cEKKB0w5 – Hidden Jun 07 '13 at 12:47
  • @Polymorphin: Probably. Perhaps you forgot the call to `QueryPerformanceFrequency`, or you forgot to divide the tick-count distance by the obtained frequency. – Andreas Rejbrand Jun 07 '13 at 12:49
  • 10
    @Andreas, I would personally suggest [`TStopWatch`](http://docwiki.embarcadero.com/Libraries/XE3/en/System.Diagnostics.TStopwatch) for Delphi XE3. [+1] – TLama Jun 07 '13 at 12:49
  • @TLama: I'm still on D2009 and know nothing about it... :( – Andreas Rejbrand Jun 07 '13 at 12:50
  • 5
    @AndreasRejbrand, `TStopWatch` is available as a class here, [`How to Accurately Measure Elapsed Time Using High-Resolution Performance Counter`](http://delphi.about.com/od/windowsshellapi/a/delphi-high-performance-timer-tstopwatch.htm). – LU RD Jun 07 '13 at 15:40
1

For the sake of having more possibilities for tackling the question, you could also use System.Classes.TThread.GetTickCount to get a current time in milliseconds to start your timer before your method, and then again after your method. The difference between these two is obviously the elapsed time in milliseconds, which you could transform into hours, seconds, etc.

Having said that, David Heffernan's proposal with TStopwatch is more elegant (and more precise?).

Stormbringer
  • 78
  • 1
  • 7
0
VAR iFrequency, iTimerStart, iTimerEnd: Int64;

procedure TimerStart;
begin
  if NOT QueryPerformanceFrequency(iFrequency)
  then MesajWarning('High resolution timer not availalbe!');
  WinApi.Windows.QueryPerformanceCounter(iTimerStart);
end;


function TimerElapsed: Double; { In miliseconds }
begin
  QueryPerformanceCounter(iTimerEnd);
  Result:= 1000 * ((iTimerEnd - iTimerStart) / ifrequency);
end;


function TimerElapsedS: string;       { In seconds/miliseconds }
begin
 if TimerElapsed < 1000
 then Result:= Real2Str(TimerElapsed, 2)+ ' ms'
 else Result:= Real2Str(TimerElapsed / 1000, 2)+ ' s';
end;
Gabriel
  • 20,797
  • 27
  • 159
  • 293