web-dev-qa-db-ja.com

関数の経過時間を計算する方法は?

Delphiの関数にかかる時間を計算する方法を知りたいのですが。

次に、使用時間を表示し、それを別の関数またはコンポーネントと比較して、より高速な関数を知りたいと思いました。

16
Hidden

System.DiagnosticsユニットのTStopwatchを使用して、システムの高解像度パフォーマンスカウンターを使用して経過時間を測定できます。

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

たとえば、タイムスパンから秒単位の時間値を読み取るには、次のようにします。

var
  Seconds: Double;
....
Seconds := Elapsed.TotalSeconds;
53
David Heffernan

QueryPerformanceCounter および QueryPerformanceFrequency 関数を使用できます。

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

  // Now (c2-c1)/f is the duration in secs of DoSomething
21

質問に取り組むためのより多くの可能性を持たせるために、System.Classes.TThread.GetTickCount現在の時間をミリ秒単位で取得して、メソッドの前にタイマーを開始し、メソッドの後にもう一度開始します。これら2つの違いは、明らかにミリ秒単位の経過時間であり、時間、秒などに変換できます。

そうは言っても、TStopwatchを使用したDavidHeffernanの提案は、よりエレガントです(そしてより正確ですか?)。

1
Stormbringer
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;