web-dev-qa-db-ja.com

ストップウォッチとタイミングイベントにSystem.DateTime.Nowを使用する

コードのパフォーマンスを追跡したいので、System.DateTime.Nowを使用して開始時間と終了時間を保存しました。コードの実行時間として、この2つの差を取りました。

違いは正確ではないように見えましたが。そこで、Stopwatchオブジェクトを使用してみました。これははるかに正確であることが判明しました。

StopwatchSystem.DateTime.Nowを使用して開始時間と終了時間の差を計算するよりも正確である理由を教えてください。

ところで、私は10分の1パーセントの話ではありません。約15〜20%の差があります。

91
Randy Minder

[〜#〜] msdn [〜#〜]

ストップウォッチは、基礎となるタイマーメカニズムのタイマーティックをカウントして経過時間を測定します。インストールされているハードウェアとオペレーティングシステムが高解像度のパフォーマンスカウンターをサポートしている場合、Stopwatchクラスはそのカウンターを使用して経過時間を測定します。それ以外の場合、Stopwatchクラスはシステムタイマーを使用して経過時間を測定します。 FrequencyおよびIsHighResolutionフィールドを使用して、ストップウォッチタイミング実装の精度と解像度を決定します。

DateTime.Nowよりも高い解像度/精度を使用します。

これらの関連リンクも確認できます。

Environment.TickCount vs DateTime.Now

DateTime.Nowは関数のパフォーマンスを測定する最良の方法ですか?

おそらくDateTimeは2番目の精度に十分ですが、それ以上のものはStopWatchをお勧めします。

74
Kelsey

DateTime値を減算するよりもはるかに正確であるため、Stopwatchクラスを使用することをお勧めします。

Stopwatch s = Stopwatch.StartNew();
// Tested code here
s.Stop();
Console.WriteLine("Elapsed Time: {0} ms", s.ElapsedMilliseconds);

残念ながら、この単純なコードでは、OSの内部で多くのアクティビティが行われているため、ほとんどの場合、正確な測定値を取得するのに十分ではありません。そのため、テストを複数回実行してから、最低時間と最高時間を削除するのが最適です。そのpuproseにとって、テストされたコードを複数回実行し、最小時間と最大時間を削除して平均時間を計算するメソッドを持つことは良い解決策です。 私のブログのサンプルテスト方法 を公開しました。

29
Pavel Vladov

this タイミング機能のパフォーマンス リンクは、正確な問題、特にこの段落について説明しています:

問題は、MSDNによると、DateTime.Now関数の解像度が10ミリ秒以上であり、2回呼び出す必要があるということです。そのため、ランタイム測定に20ミリ秒以上の変動が生じます。多くの場合、関数呼び出しはこの20ミリ秒のウィンドウよりもはるかに速く戻るため、これは十分ではありません。

編集:2番目のDateTime.Nowがストップウォッチメソッドの終了時とは異なる時間に呼び出されているように聞こえます。

8
Robb