Stopwatchクラスは、名前の通りストップウォッチのように時間経過を計測するクラス。 OSおよびハードウェアが対応している場合は、自動的に高分解能パフォーマンスカウンタを使用して計測を行うため、一般的にDateTime.Tickなどを使った場合よりも高い精度で計測を行うことが出来る。 高分解能パフォーマンスカウンタに対応していない場合は、システムタイマを使用して計測を行う。
高分解能パフォーマンスカウンタとシステムタイマのどちらが使用されるかどうかは、IsHighResolutionプロパティで参照できる。 また、分解能はFrequencyプロパティで参照できる。
Stopwatchクラスは、Start()メソッドで時間経過の計測を開始し、Stop()メソッドで計測を終了する。 Stopwatchクラスは、Start()およびStop()する度に時間経過を累積して計上する。 そのため、計上した時間をクリアして計測しなおしたい場合はReset()メソッドを呼ぶ必要がある。
高分解能パフォーマンスカウンタが使用される場合は、内部的にQueryPerformanceFrequency()およびQueryPerformanceCounter() (いずれもWin32 API)が呼ばれる。 この時、GetTimestamp()はQueryPerformanceCounter()の結果に基づいた値となる。 システムタイマが使用される場合は、GetTimestamp()はDateTime.Tickと同値となる。
1秒スリープする前後のタイムスタンプと実際の経過時間を計測する。
using System; using System.Diagnostics; using System.Threading; public class StopwatchSample { public static void Main() { // Stopwatchの能力を表示 Console.WriteLine( "Stopwatch.Frequency: {0}MHz", Stopwatch.Frequency / 1000000 ); Console.WriteLine( "Stopwatch.IsHighResolution: {0}", Stopwatch.IsHighResolution ); Stopwatch watch = new Stopwatch(); // 3回試行 for ( int count = 0; count < 3; count++ ) { Console.WriteLine( "Test#{0}", count ); Console.WriteLine( "Timestamp(before): {0}", Stopwatch.GetTimestamp() ); watch.Start(); // 1秒スリープする Thread.Sleep( 1000 ); watch.Stop(); Console.WriteLine( "Timestamp(after): {0}", Stopwatch.GetTimestamp() ); Console.WriteLine( "Elapsed milliseconds: {0}", watch.ElapsedMilliseconds ); Console.WriteLine( "Elapsed ticks: {0}", watch.ElapsedTicks ); watch.Reset(); } } }
Stopwatch.Frequency: 3MHz Stopwatch.IsHighResolution: True Test#0 Timestamp(before): 4468021555 Timestamp(after): 4471571779 Elapsed milliseconds: 991 Elapsed ticks: 3549773 Test#1 Timestamp(before): 4471574066 Timestamp(after): 4475149159 Elapsed milliseconds: 998 Elapsed ticks: 3574602 Test#2 Timestamp(before): 4475151335 Timestamp(after): 4478730883 Elapsed milliseconds: 999 Elapsed ticks: 3579056
Stopwatch.Frequency: 10MHz Stopwatch.IsHighResolution: True Test#0 Timestamp(before): 2359336605891 Timestamp(after): 2359346610670 Elapsed milliseconds: 1000 Elapsed ticks: 10003551 Test#1 Timestamp(before): 2359346614248 Timestamp(after): 2359356615817 Elapsed milliseconds: 1000 Elapsed ticks: 10001479 Test#2 Timestamp(before): 2359356616492 Timestamp(after): 2359366617684 Elapsed milliseconds: 1000 Elapsed ticks: 10001077
StartNewメソッドを使用するとより簡単に記述できる。
using System; using System.Diagnostics; using System.Threading; public class StopwatchSample { public static void Main() { // 3回試行 for ( int count = 0; count < 3; count++ ) { Console.WriteLine( "Test#{0}", count ); Console.WriteLine( "Timestamp(before): {0}", Stopwatch.GetTimestamp() ); Stopwatch watch = Stopwatch.StartNew(); // 1秒スリープする Thread.Sleep( 1000 ); watch.Stop(); Console.WriteLine( "Timestamp(after): {0}", Stopwatch.GetTimestamp() ); Console.WriteLine( "Elapsed milliseconds: {0}", watch.ElapsedMilliseconds ); Console.WriteLine( "Elapsed ticks: {0}", watch.ElapsedTicks ); } } }