.NET CoreでBenchmarkDotNetを利用する

公開日:2018-12-11
最終更新:2018-12-11

C#でTypeをキーにしたDictionaryのパフォーマンス比較と最速コードの実装 - Grani Engineering Blog をベースに、.Net CoreでBenchmarkDotNetを利用する。

環境

  • Windows 7
  • .NET Core SDK 2.1.403

作業手順

.NET Coreはインストール済みとして話を進める。

1. 実行ファイルテンプレート作成

作成したいフォルダで以下のコマンドを入力する。必要なファイルが自動作成される。

dotnet new console  

2. BenchmarkDotNetのインストール

続けて以下のコマンドを入力する。バージョンはNuGet Gallery | BenchmarkDotNet 0.11.3 より最新かどうか確認する。

dotnet add package BenchmarkDotNet --version 0.11.3  

手入力しなくても、「.NET CLI」タブを開いてコピペすればOK

3. 必要なファイルの追加

3.1 コンフィグファイル作成

using BenchmarkDotNet.Configs;  
using BenchmarkDotNet.Diagnosers;  
using BenchmarkDotNet.Exporters;  
using BenchmarkDotNet.Jobs;  

namespace Benchmark{  
    public class BenchmarkConfig : ManualConfig{  
        public BenchmarkConfig(){  
            Add(MarkdownExporter.GitHub); // Markdown形式での出力  
            Add(MemoryDiagnoser.Default);  
            Add(Job.ShortRun); // テスト回数をデフォルトより少なくする  
        }  
    }  
}  

3.2 ベンチマーククラス作成

※テストコードは適当なので適宜読み替えてください。

using System;  
using System.Collections.Generic;  
using System.Linq;  
using BenchmarkDotNet.Attributes;  

namespace Benchmark{  
    //先程のコンフィグファイルを指定  
    [Config(typeof(BenchmarkConfig))]  
    public class DictionaryBenckmark{  
        List<string> baseList;  

        //(おそらく)各テスト実行前に1回実行  
        [GlobalSetup]  
        public void Setup(){  
            baseList = Enumerable.Range(0,3000).OrderBy(_ => Guid.NewGuid()).Select(x => x.ToString()).ToList();  
        }  

        // ベンチマーク本体 Baseline = true をつけるとこれを基準にRatioを出してくれる  
        [Benchmark(Baseline = true)]  
        public string[] NonSorted(){  
            var dict = new Dictionary<int, string>();  
            foreach(var item in baseList){  
                var num = int.Parse(item);  
                dict[num] = item;  
            }  

            return dict.OrderBy(x => x.Key).Select( x => x.Value ).ToArray();  
        }  

        // ベンチマーク本体  
        [Benchmark]  
        public string[] Sorted(){  
            var dict = new SortedDictionary<int, string>();  
            foreach(var item in baseList){  
                var num = int.Parse(item);  
                dict[num] = item;  
            }  

            return dict.Values.ToArray();  
        }  
    }  
}  

3.3 ベンチマーククラスを呼び出すコードをMainに記載

using System;  
using BenchmarkDotNet.Running;  

namespace Benchmark  
{  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            // 作成したクラスを指定  
            // 複数ベンチマーククラスを作成した場合はここに続けて書く  
            var switcher = new BenchmarkSwitcher(new[]  
            {  
                typeof(DictionaryBenckmark)  
            });  

            args = new string[] { "0" }; // ここのargsを指定している部分がイマイチわからない...  
            switcher.Run(args); // 実行  
        }  
    }  
}  

4. 実行

実行する際、Debugビルドでは実行してくれないのでReleaseビルドにする。以下のコマンドで実行可能。

dotnet run -c release  

実行後、どのベンチマークを実行するか聞かれる。以下実行例。

Available Benchmark:  
  #0 DictionaryBenckmark  


You should select the target benchmark(s). Please, print a number of a benchmark (e.g. '0') or a contained benchmark caption (e.g. 'DictionaryBenckmark'):  
If you want to select few, please separate them with space ` ` (e.g. `1 2 3`)  
You can also provide the class name in console arguments by using --filter. (e.g. '--filter *DictionaryBenckmark*'):  

この画面で0を入力してEnterを押すと#0(ここではDictionaryBenckmark)が実行される。

結果の確認

BenchmarkDotNet.Artifacts\resultsディレクトリ内に先程の結果が格納される。例で記載したConfigの場合、CSV/Markdown/HTMLで出力される。



BenchmarkDotNet=v0.11.3, OS=Windows 7 SP1 (6.1.7601.0)  
Intel Core i7-4770K CPU 3.50GHz (Haswell), 1 CPU, 8 logical and 4 physical cores  
Frequency=3418027 Hz, Resolution=292.5664 ns, Timer=TSC  
.NET Core SDK=2.1.403  
  [Host]   : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT  
  ShortRun : .NET Core 2.1.5 (CoreCLR 4.6.26919.02, CoreFX 4.6.26919.02), 64bit RyuJIT  

Job=ShortRun  IterationCount=3  LaunchCount=1    
WarmupCount=3    
Method Mean Error StdDev Ratio Gen 0/1k Op Gen 1/1k Op Gen 2/1k Op Allocated Memory/Op
NonSorted 809.6 us 38.77 us 2.125 us 1.00 60.5469 30.2734 30.2734 304.81 KB
Sorted 1,280.0 us 46.79 us 2.565 us 1.58 41.0156 9.7656 - 188.01 KB

とりあえず、「Mean」「Ratio(Baselineを指定している場合)」「Allocated Memory/Op」を見ていれば大丈夫だと思われる。

記事が少しでもいいなと思ったらクラップを送ってみよう!
18
+1
@maccyoの技術ブログ(予定) C#/VB.NET/Kotlin/Delphi

よく一緒に読まれている記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう
目次をみる

技術ブログをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

技術ブログを開設する

Qrunchでアウトプットをはじめよう

Qrunch(クランチ)は、ITエンジニアリングに携わる全ての人のための技術ブログプラットフォームです。

Markdownで書ける

ログ機能でアウトプットを加速

デザインのカスタマイズが可能

技術ブログ開設

ここから先はアカウント(ブログ)開設が必要です

英数字4文字以上
.qrunch.io
英数字6文字以上
ログインする