【C#】BenchmarkDotNetを使って処理時間を計測する方法

C# の処理の実行時間の測定やメモリ使用量、GCの量を正確に計測できるライブラリ「BenchmarkDotNet」の最速セットアップ & 使用方法の紹介したいと思います。実行時間を測定するために Stopwatch クラスを使用する方法もありますが、このライブラリを使ったほうがより正確に実行時間を計測できます。

確認環境

  • VisualStudio 2022
  • .NET6
  • Windows11

VisualStudio の IDE 上で操作しています。

セットアップ手順

手順は概ね以下の通りです。

  1. NuGet から BenchmarkDotNet をインストールする
  2. テストしたい処理を書く、クラス、メソッドに属性を付ける
  3. Release ビルドで実行する

で、IDE 上から Release ビルドしてそのまま実行してもいいですし、いったん Relese フォルダ内の exe をコンソールから実行してもいいです。コンソールから実行したほうが計測が安定すると思います。

計測コードの書き方

using BenchmarkDotNet.Running; // 追加する

internal class Program
{
    private static void Main(string[] args)
    {
        BenchmarkRunner.Run<Test>(); // メインにテストしたいクラスを指定する
    }
}

// ★計測対象のクラスに追加する
[MemoryDiagnoser]
[RankColumn]
public class Test
{
    // ★事前のデータ初期化など最初のセットアップ
    [GlobalSetup]
    public void Setup()
    {
        // フィールド変数の初期化とかリストデータ作成etc...
    }

    // ★対象のメソッドに属性を追加する
    [Benchmark]
    public void Case1()
    {
        // 計測したい実装を書く
    }

    [Benchmark]
    public void Case2()
    {
        // 計測したい実装を書く
    }
}

各属性の説明です。

  • MemoryDiagnoser:結果にメモリ使用量の統計を出力するように指定します。
  • RankColumn:結果に処理速度の順位を出力するように指定します。
  • Benchmark:計測したいメソッドに追加します。

これで実行すると、以下のように結果がサマリーで表示されます。

| Method |     Mean |    Error |   StdDev | Rank |   Gen0 | Allocated |
|------- |---------:|---------:|---------:|-----:|-------:|----------:|
|  Case1 | 17.31 us | 0.083 us | 0.074 us |    1 | 1.3733 |   5.62 KB |
|  Case2 | 18.73 us | 0.108 us | 0.101 us |    2 | 2.1973 |   9.01 KB |

結果の見方は以下の通りです。

* Method:計測対象のメソッド名
* Mean:計測対象のメソッドの処理時間
* Error:99%の確率で母平均が含まれるような範囲
* StdDev:すべての測定値の標準偏差です。平均値からのデータの散らばりの程度
* Rank:Mean の順位
* Gen0:1000回処理ごとのGC(世代0)の回収数(オブジェクトの数?)
* Allocated:一回ごとのメモリ割り当て量

結局色々オプションがあっても、Mean と Allocated くらいしか見ないのでこれで使い方は十分だと思います。

よく、Benchmark のみ指定して計測している方法がネットで見られますが MemoryDiagnoser は付けておいたほうが良いです。通常は確認しにくい、メモリ使用量の項目が出るようになります。