Stopwatchクラスは、名前の通りストップウォッチのように時間経過を計測するクラス。 OSおよびハードウェアが対応している場合は、自動的に高分解能パフォーマンスカウンタを使用して計測を行うため、一般的にDateTime.TicksやEnvironment.TickCountなどを使った場合よりも高い精度で計測を行うことが出来る。 高分解能パフォーマンスカウンタに対応していない場合は、システムタイマを使用して計測を行う。
高分解能パフォーマンスカウンタとシステムタイマのどちらが使用されるかどうかは、IsHighResolutionプロパティで参照できる。 また、分解能はFrequencyプロパティで参照できる。
Stopwatchクラスは、Start()メソッドで時間経過の計測を開始し、Stop()メソッドで計測を終了する。 Stopwatchクラスは、Start()およびStop()する度に時間経過を累積して計上する。 そのため、計上した時間をクリアして計測しなおしたい場合はReset()メソッドを呼ぶ必要がある。
高分解能パフォーマンスカウンタが使用される場合は、内部的にQueryPerformanceFrequency()およびQueryPerformanceCounter() (いずれもWin32 API)が呼ばれる。 この時、GetTimestamp()はQueryPerformanceCounter()の結果に基づいた値となる。 システムタイマが使用される場合は、GetTimestamp()はDateTime.Tickと同値となる。
主なコンストラクタ
- Stopwatch()
- インスタンスを生成する。
主なメソッド
- void Start()
- 計測を開始する。
- void Stop()
- 計測を停止する。
- void Reset()
- 計上した経過時間をリセットする。
- void Restart()
- 計上した経過時間をリセットし、計測を再度開始する。 Reset() + Start()と同等。 (.NET Framework 4以降)
- static Stopwatch StartNew()
- Stopwatchのインスタンスを作成するのと同時に、計測を開始する。
- static long GetTimestamp()
- 現在のタイマ刻み数(タイマの持つ分解能で計測出来る時間間隔を計測した回数)を取得する。
主なプロパティ
- Frequency (static long)
- タイマの持つ分解能で計測できる1秒あたりの計測回数を表す。
- IsHighResolution (static long)
- タイマが高分解能パフォーマンスカウンタを使用している場合はtrue、システムタイマを使用している場合はfalse。
- Elapsed (TimeSpan)
- 計測を開始してから終了するまでの時間経過の累積値をTimeSpan型で表す。
- ElapsedMilliseconds (long)
- 計測を開始してから終了するまでの時間経過の累積値をミリ秒単位で表す。
- ElapsedTicks (long)
- 計測を開始してから終了するまでの時間経過の累積値をタイマ刻み数単位で表す。
主な呼び出し順序
- new Stopwatch()
- Start()
- Stop()
- Reset()
もしくは
- StartNew()
- Stop()
- Reset()
使用例
1秒スリープする前後のタイムスタンプと実際の経過時間を計測する。
using System;
using System.Diagnostics;
using System.Threading;
class Sample {
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();
}
}
}
Imports System
Imports System.Diagnostics
Imports System.Threading
Class Sample
Shared Sub Main()
' Stopwatchの能力を表示
Console.WriteLine("Stopwatch.Frequency: {0}MHz", Stopwatch.Frequency \ 1000000)
Console.WriteLine("Stopwatch.IsHighResolution: {0}", Stopwatch.IsHighResolution)
Dim watch As New Stopwatch()
' 3回試行
For count As Integer = 0 To 2
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()
Next
End Sub
End Class
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
同じ処理で繰り返し計測するような場合はRestartメソッドを使用するとより簡単に記述できる。
using System;
using System.Diagnostics;
using System.Threading;
class Sample {
static void Main()
{
Stopwatch watch = new Stopwatch();
// 3回試行
for (int count = 0; count < 3; count++) {
// カウンタをリセットすると同時にカウントを再開
watch.Restart();
// 1秒スリープする
Thread.Sleep(1000);
Console.WriteLine("Test#{0} Elapsed: {1}", count, watch.Elapsed);
}
}
}
Imports System
Imports System.Diagnostics
Imports System.Threading
Class Sample
Shared Sub Main()
Dim watch As New Stopwatch()
' 3回試行
For count As Integer = 0 To 2
' カウンタをリセットすると同時にカウントを再開
watch.Restart()
' 1秒スリープする
Thread.Sleep(1000)
Console.WriteLine("Test#{0} Elapsed: {1}", count, watch.Elapsed)
Next
End Sub
End Class