Windowsで時間計測を行う場合、QueryPerformanceCounterを使用すれば比較的容易にマイクロ秒単位での実時間計測が出来る為、今まで使用してきた人も比較的多いのではないかと思う。
(それ以外のAPIは全てミリ秒単位の計測になるため、特に音楽系での用途には若干精度が不足する場面もあった為、好んでQueryPerformanceCounterを使用していた人も多いと思う)
で、このQueryPerformanceCounterの代わりに使用できるAPIとして.NETで用意されているのがSystem.Diagnostics.Stopwatchクラスなわけだ。
このクラスは実のところ殆どQueryPerformanceCounterそっくりに出来ており、おそらく.NETを使用してマイクロ秒単位の時間計測を行いたい場合はこのクラスを使用する事がほぼ決定事項になるのではないかと思う。
で、このクラスの実装方法なんだけど、もしこのクラスが内部でQueryPerformanceCounterとQueryPerformanceFrequencyを使用していた場合には問題になる。
QueryPerformanceCounterについての問題を実験されたサイトが
こちら。
QueryPerformanceCounterの内部実装がどうなっているのかはわからないのだが、実験結果から不正確な時間が帰る場合があるということがわかっている以上、そのまま無闇に使用してはならないという事になると思う。
(個人的には、そもそもSleep(1000)で正確に1秒きっかり停止しているかどうかから検証すべきな気もしてますが)
今までも、そもそもQueryPerformanceCounterが使用出来ないハードかどうかを調べるために、戻り値が0かどうかをチェックするようなコードは組んでいたと思うのだが、もうそれだけでは足りないという事になりそうだ。
そしてユーザープログラムがQueryPerformanceCounterを直接呼んでいる場合は値がおかしいかどうかを判定して使用するかどうかを判断すれば良いのだが、Stopwatchクラスの場合はその判断をクラス内部で行ってしまっている為、もしここでQueryPerformanceCounterを呼ぶ方法で実装されており、且つ戻り値が0の時には使用出来ない(=DateTimeを使用する)と判定しているのであれば、ユーザープログラム側で更にStopwatchの計測時間が本当に正しいのかどうかを改めて判定させる必要があるという事になるのではないかと思う。
Stopwatchクラスの場合、今までユーザープログラム側で行っていた使用出来るか出来ないか判定をクラス内部で行っている、=Stopwatchクラスの返す値を常に信頼してプログラムを書いている、という人も居るのではないだろうか?
そういう人の場合、少なくない変更が必要になる可能性があるという事を上の実験は示していると思う。
(まぁ、そもそもStopwatchクラスが正しくない値をかえすかどうかの実験やってないんで、なんとも言えないんですけどねw)