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オーダーレベルでの処理時間計測には向かない)

