C#で「コードの処理する時間」を計測する
C言語などでは、時間関数などを駆使してコードの処理時間を計測します。
C#でコードの処理時間を計測する場合、Stopwatchクラス(名前空間System.Diagnostics)というクラスが.NET Frameworkに用意されています。
このStopwatchクラスを使ってコードの処理時間計測の性能を評価してみました。
評価方法
同じ処理を100回繰り返し、その処理時間をメモリ上に保持する。
処理対象は、処理時間が一定(のはずである)System.Threading.Sleep()のみとする。
(Sleep()はよく処理の待ちを発生させるときに使用される)
C#の場合、ビルド方法は2種類(Debugビルド、Releaseビルド)があるため、この2種類でも評価を行う。
評価に使用したコード
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading; // <-- Sleep()のために追加 using System.Diagnostics; namespace StopWatchTest { class Program { static void Main(string[] args) { Stopwatch sw = new Stopwatch(); int count = 0; // カウンタ int test_num = 100; // テストの実行回数 List<TimeSpan> result = new List<TimeSpan>(); Console.WriteLine("計測を開始します。"); for (count = 0; count < test_num; count++) { sw.Start(); // <-- StopWatchによる計測開始 Thread.Sleep(30); // 30ミリ秒間待つ sw.Stop(); // <-- StopWatchによる計測終了 result.Add(sw.Elapsed); // 結果を保持させる sw.Reset(); // <-- Resetして再度計測 } Console.WriteLine("計測を完了しました"); count = 0; TimeSpan total = new TimeSpan(); foreach (TimeSpan ts in result) { total += ts; count++; Console.WriteLine("{0}\t{1}", count, ts.TotalMilliseconds.ToString()); } Console.WriteLine("経過時間の合計({0}回) = {1}(msec)", count, total.TotalMilliseconds.ToString()); Console.WriteLine("経過時間の平均 = {0}(msec)", (total.TotalMilliseconds / count)); Console.WriteLine("経過時間の分解能 (1秒あたり) = {0}", Stopwatch.Frequency); Console.ReadKey(); } } }
計測結果
Debugビルド | Releaseビルド | |
合計(100回)(msec) | 3135.5654 | 3134.5757 |
平均(msec) | 31.3557 | 31.3458 |
DebugビルドとReleaseビルドについては、DebugビルドがReleaseビルドより遅い。
実際の処理時間より平均1.3msecほど、計測時間に遅れが発生する(Debugビルド・Releaseビルドともに)。
計測結果のグラフ
初回のみ10msecほど遅れがある。
4回に1回の割合で2msec前後の遅れが発生する(ばらつきがある)。
結果
Stopwatchクラスは、時間計測のための機能として、実装がとても簡単にできる。
コードの処理時間の「目安」(秒単位や100msec単位くらいまで)として、ある程度使える。
(ただし、msecオーダーレベルでの処理時間計測には向かない)