測定実行時のクライアントまで、フルのC#
-
29-09-2019 - |
質問
測りたいの執行のコードをとったう最良の方法は?
オプション1:
DateTime StartTime = DateTime.Now;
//Code
TimeSpan ts = DateTime.Now.Subtract(StartTime);
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds / 10);
Console.WriteLine(elapsedTime, "RunTime");
オプション2:利用システム。診断;
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
//Code
stopWatch.Stop();
// Get the elapsed time as a TimeSpan value.
TimeSpan ts = stopWatch.Elapsed;
// Format and display the TimeSpan value.
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds / 10);
Console.WriteLine(elapsedTime, "RunTime");
こんなのためのベンチマーキング、実際に一部のものに限ります。の機能を実行する関連するデータです。なしが必要な原子またはハイパー。
るオプションは、より良い生産コード又は誰のものを使っておけば間違いない別のもいいですか?
解決
Stopwatch
クラスは、経過時間を測定するように特別に設計されており、(ハードウェアで利用可能な場合)、基礎となる高周波ハードウェアタイマーを使用して、良好な粒度/精度を提供する可能性があります。これは最良の選択のようです。
ishighResolutionプロパティ 高解像度のタイミングが利用可能かどうかを判断するために使用できます。ドキュメントによると、このクラスは、正確なタイミングのために「利用可能な最高の」Win32 APIのラッパーを提供します。
具体的には、
Frequency
フィールドとGetTimestamp
メソッドは、管理されていないWin32 APIの代わりに使用できますQueryPerformanceFrequency
とQueryPerformanceCounter
.
これらのWin32 API [ここ]およびリンクされたMSDNドキュメントの詳細な背景があります 2.
高解像度タイマー
カウンターは、プログラミングで使用される一般的な用語であり、増分変数を参照します。一部のシステムには、高解像度の経過時間を提供する高解像度のパフォーマンスカウンターが含まれます。
システムに高解像度のパフォーマンスカウンターが存在する場合、 QueryPerformanceFrequency周波数を1秒間に表現する機能。カウントの値はプロセッサに依存します。たとえば、一部のプロセッサでは、カウントはプロセッサクロックのサイクルレートになる可能性があります。
QueryPerformAncecounter 関数高解像度パフォーマンスカウンターの現在の値を取得します。コードのセクションの最初と終了時にこの関数を呼び出すことにより、アプリケーションは基本的にカウンターを高解像度タイマーとして使用します。たとえば、それを仮定します QueryPerformanceFrequency 高解像度パフォーマンスカウンターの頻度が毎秒50,000カウントであることを示します。アプリケーションが呼び出す場合 QueryPerformAncecounter タイミングのコードのセクションの直前と直後に、カウンター値はそれぞれ1500カウントと3500カウントになる可能性があります。これらの値は、コードが実行されている間に.04秒(2000カウント)が経過したことを示します。
他のヒント
それだけではありません StopWatch
より正確ですが、それもそうです DateTime.Now
状況によっては誤った結果が得られます。
たとえば、夏時間のスイッチオーバー中に何が起こるかを考えてください - DateTime.Now
実際に与えることができます ネガティブ 答え!
私は一般的に使用 StopWatch
このような状況です。
から MSDN ページ:
ストップウォッチ
セットを提供方法 物件のすることができるよ を正確に測定経過時間。
以下のポストにして使用しますを比較しに、実行時間のLINQ vs PLINQ:
あなたはそれがそれほど重要ではないと言うので、どちらもパフォーマンスを傷つけることはありません。 StopWatchはより適切なようです - あなたは時間から時間を差し引くだけであり、別のものからの日付ではありません。日付のものには、メモリが少し時間がかかり、CPUに対処する時間がかかります。いくつかの場所で再利用することを計画している場合に備えて、コードをクリーンにする方法もあります。過負荷 using
頭に浮かぶ。例を検索します。 OK、盗まれたコード:
http://stevesmithblog.com/blog/great-uses-of-using-statement-in-c-/
public class ConsoleAutoStopWatch : IDisposable
{
private readonly Stopwatch _stopWatch;
public ConsoleAutoStopWatch()
{
_stopWatch = new Stopwatch();
_stopWatch.Start();
}
public void Dispose()
{
_stopWatch.Stop();
TimeSpan ts = _stopWatch.Elapsed;
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
ts.Hours, ts.Minutes, ts.Seconds,
ts.Milliseconds / 10);
Console.WriteLine(elapsedTime, "RunTime");
}
}
private static void UsingStopWatchUsage()
{
Console.WriteLine("ConsoleAutoStopWatch Used: ");
using (new ConsoleAutoStopWatch())
{
Thread.Sleep(3000);
}
}
どちらもあなたのニーズにうまく合うでしょうが、私は使用すると言うでしょう StopWatch
. 。なんで?それはあなたがしているタスクのためのものだからです。
現在の日付/時刻を返すために構築された1つのクラスがあります。これは、タイミングのタイミングに使用でき、タイミングのために特別に設計された1つのクラスがあります。
この場合、違いは、ミリ秒の精度が必要な場合にのみ存在します(その場合 StopWatch
より正確です)が、あなたが探しているタスクに特にツールが存在する場合、一般的なプリンシパルとして、それはより良いものです。
私はこのようなことをするための小さなクラスを持っています。ストップウォッチクラスを使用します - C#マイクロパフォーマンステスト.
例えば。
var tester = new PerformanceTester(() => SomeMethod());
tester.MeasureExecTime(1000);
Console.Writeline(string.Format("Executed in {0} milliseconds", tester.AverageTime.TotalMilliseconds));
以下のコードを使用します
DateTime dExecutionTime;
dExecutionTime = DateTime.Now;
TimeSpan span = DateTime.Now.Subtract(dExecutionTime);
lblExecutinTime.Text = "total time taken " + Math.Round(span.TotalMinutes,2) + " minutes . >>---> " + DateTime.Now.ToShortTimeString();
私はハミッシュの答えを簡素化し、他の場所にログする必要がある場合に備えて、もう少し一般的にしました。
public class AutoStopWatch : Stopwatch, IDisposable {
public AutoStopWatch() {
Start();
}
public virtual void Dispose() {
Stop();
}
}
public class AutoStopWatchConsole : AutoStopWatch {
private readonly string prefix;
public AutoStopWatchConsole(string prefix = "") {
this.prefix = prefix;
}
public override void Dispose() {
base.Dispose();
string format = Elapsed.Days > 0 ? "{0} days " : "";
format += "{1:00}:{2:00}:{3:00}.{4:00}";
Console.WriteLine(prefix + " " + format.Format(Elapsed.Days, Elapsed.Hours, Elapsed.Minutes, Elapsed.Seconds, Elapsed.Milliseconds / 10));
}
}
private static void Usage() {
Console.WriteLine("AutoStopWatch Used: ");
using (var sw = new AutoStopWatch()) {
Thread.Sleep(3000);
Console.WriteLine(sw.Elapsed.ToString("h'h 'm'm 's's'"));
}
Console.WriteLine("AutoStopWatchConsole Used: ");
using (var sw = new AutoStopWatchConsole()) {
Thread.Sleep(3000);
}
}