BenchMarkDotNetは、メソッドをベンチマークに変換し、パフォーマンスを追跡し、再現可能な測定実験を共有するのに役立ちます。ユニットテストを書くことほど難しくありません!ボンネットの下では、パフォーマイザーの統計エンジンのおかげで、信頼できる正確な結果を保証する多くの魔法を実行します。 BenchmarkDotNetは、人気のあるベンチマークの間違いからあなたを保護し、ベンチマーク設計または取得した測定に何か問題があるかどうかを警告します。結果は、実験に関するすべての重要な事実を強調するユーザーフレンドリーなフォームで提示されます。 BenchmarkDotNetは、.NETランタイム、.NETコンパイラ、.NETパフォーマンスなどを含む22000以上のGitHubプロジェクトで既に採用されています。
ベンチマークの作成を開始するのは簡単です。次の例をご覧ください(コピー患者バージョンはこちらです):
[ SimpleJob ( RuntimeMoniker . Net472 , baseline : true ) ]
[ SimpleJob ( RuntimeMoniker . NetCoreApp30 ) ]
[ SimpleJob ( RuntimeMoniker . NativeAot70 ) ]
[ SimpleJob ( RuntimeMoniker . Mono ) ]
[ RPlotExporter ]
public class Md5VsSha256
{
private SHA256 sha256 = SHA256 . Create ( ) ;
private MD5 md5 = MD5 . Create ( ) ;
private byte [ ] data ;
[ Params ( 1000 , 10000 ) ]
public int N ;
[ GlobalSetup ]
public void Setup ( )
{
data = new byte [ N ] ;
new Random ( 42 ) . NextBytes ( data ) ;
}
[ Benchmark ]
public byte [ ] Sha256 ( ) => sha256 . ComputeHash ( data ) ;
[ Benchmark ]
public byte [ ] Md5 ( ) => md5 . ComputeHash ( data ) ;
}BenchmarkDotNetは、すべてのランタイムでベンチマークを自動的に実行し、測定値を集約し、最も重要な情報で概要テーブルを印刷します。
BenchmarkDotNet=v0.12.0, OS=Windows 10.0.17763.805 (1809/October2018Update/Redstone5)
Intel Core i7-7700K CPU 4.20GHz (Kaby Lake), 1 CPU, 8 logical and 4 physical cores
[ Host ] : .NET Framework 4.7.2 (4.7.3468.0), X64 RyuJIT
Net472 : .NET Framework 4.7.2 (4.7.3468.0), X64 RyuJIT
NetCoreApp30 : .NET Core 3.0.0 (CoreCLR 4.700.19.46205, CoreFX 4.700.19.46214), X64 RyuJIT
NativeAot70 : .NET 7.0.0-preview.4.22172.7, X64 NativeAOT
Mono : Mono 6.4.0 (Visual Studio), X64
| Method | Runtime | N | Mean | Error | StdDev | Ratio |
| ------- | -------------- | ------ | -----------: | ----------: | ----------: | ------: |
| Sha256 | .NET 4.7.2 | 1000 | 7.735 us | 0.1913 us | 0.4034 us | 1.00 |
| Sha256 | .NET Core 3.0 | 1000 | 3.989 us | 0.0796 us | 0.0745 us | 0.50 |
| Sha256 | NativeAOT 7.0 | 1000 | 4.091 us | 0.0811 us | 0.1562 us | 0.53 |
| Sha256 | Mono | 1000 | 13.117 us | 0.2485 us | 0.5019 us | 1.70 |
| | | | | | | |
| Md5 | .NET 4.7.2 | 1000 | 2.872 us | 0.0552 us | 0.0737 us | 1.00 |
| Md5 | .NET Core 3.0 | 1000 | 1.848 us | 0.0348 us | 0.0326 us | 0.64 |
| Md5 | NativeAOT 7.0 | 1000 | 1.817 us | 0.0359 us | 0.0427 us | 0.63 |
| Md5 | Mono | 1000 | 3.574 us | 0.0678 us | 0.0753 us | 1.24 |
| | | | | | | |
| Sha256 | .NET 4.7.2 | 10000 | 74.509 us | 1.5787 us | 4.6052 us | 1.00 |
| Sha256 | .NET Core 3.0 | 10000 | 36.049 us | 0.7151 us | 1.0025 us | 0.49 |
| Sha256 | NativeAOT 7.0 | 10000 | 36.253 us | 0.7076 us | 0.7571 us | 0.49 |
| Sha256 | Mono | 10000 | 116.350 us | 2.2555 us | 3.0110 us | 1.58 |
| | | | | | | |
| Md5 | .NET 4.7.2 | 10000 | 17.308 us | 0.3361 us | 0.4250 us | 1.00 |
| Md5 | .NET Core 3.0 | 10000 | 15.726 us | 0.2064 us | 0.1930 us | 0.90 |
| Md5 | NativeAOT 7.0 | 10000 | 15.627 us | 0.2631 us | 0.2461 us | 0.89 |
| Md5 | Mono | 10000 | 30.205 us | 0.5868 us | 0.6522 us | 1.74 |
測定されたデータは、プロットを含むさまざまな形式(MD、HTML、CSV、XML、JSONなど)にエクスポートできます。
サポートされているランタイム: .NET 5+、.NETフレームワーク4.6.1+、.NET Core 3.1+、Mono、Nativeaot
サポート言語: C#、F#、Visual Basic
サポートされているOS: Windows、Linux、MacOS
サポートされているアーキテクチャ: X86、X64、ARM、ARM64、WASM、LOONGARCH64
BenchmarkDotNetには、包括的なパフォーマンス調査に不可欠な多くの機能があります。 4つの側面が、これらの機能の設計を定義します:シンプルさ、自動化、信頼性、親しみやすさ。
ベンチマークを書きたい場合は、経験豊富なパフォーマンスエンジニアである必要はありません。シンプルなAPIを使用して、非常に複雑なパフォーマンス実験を宣言スタイルで設計できます。
たとえば、ベンチマークをパラメーター化する場合は、 [Params(1, 2, 3)]を使用してフィールドまたはプロパティをマークします。BenchmarkDotNetは、指定されたすべての値を列挙し、各ケースのベンチマークを実行します。ベンチマークを互いに比較したい場合は、ベンチマークの1つを[Benchmark(Baseline = true)]を介してベースラインとしてマークします。BenchmarkDotNetは、他のすべてのベンチマークと比較します。さまざまな環境でパフォーマンスを比較したい場合は、ジョブを使用してください。たとえば、 [SimpleJob(RuntimeMoniker.NetCoreApp31)]および[SimpleJob(RuntimeMoniker.Mono)]を介して.NET Core 3.1およびMonoですべてのベンチマークを実行できます。
属性が気に入らない場合は、Fluentスタイルを介してAPIのほとんどを呼び出して、次のようにコードを書き込むことができます。
ManualConfig . CreateEmpty ( ) // A configuration for our benchmarks
. AddJob ( Job . Default // Adding first job
. WithRuntime ( ClrRuntime . Net472 ) // .NET Framework 4.7.2
. WithPlatform ( Platform . X64 ) // Run as x64 application
. WithJit ( Jit . LegacyJit ) // Use LegacyJIT instead of the default RyuJIT
. WithGcServer ( true ) // Use Server GC
) . AddJob ( Job . Default // Adding second job
. AsBaseline ( ) // It will be marked as baseline
. WithEnvironmentVariable ( "Key" , "Value" ) // Setting an environment variable
. WithWarmupCount ( 0 ) // Disable warm-up stage
) ;コマンドラインエクスペリエンスを好む場合は、コンソールアプリケーションでコンソール引数を介してベンチマークを構成できます(他のタイプのアプリケーションはサポートされていません)。
信頼できるベンチマークには、常に多くのボイラープレートコードが含まれています。
典型的なケースであなたがすべきことについて考えてみましょう。まず、パイロット実験を実行し、最良の方法の呼び出しを決定する必要があります。次に、いくつかのウォームアップ反復を実行し、ベンチマークが定常状態を達成したことを確認する必要があります。その後、主な反復を実行し、いくつかの基本統計を計算する必要があります。ベンチマーク内のいくつかの値を計算する場合は、何らかの形で使用して、死んだコードの排除を防ぐ必要があります。ループを使用する場合は、結果に対するループの展開の効果(プロセッサアーキテクチャに依存する可能性があります)に注意する必要があります。結果が得られたら、マルチモダリティや非常に高い外れ値など、得られたパフォーマンス分布の特別な特性を確認する必要があります。また、インフラストラクチャのオーバーヘッドを評価し、結果から控除する必要があります。いくつかの環境をテストする場合は、それぞれの環境を実行し、結果を手動で集約する必要があります。
このコードをゼロから書くと、間違いを犯して測定を台無しにするのは簡単です。ベンチマーク中に従うべき完全なチェックリストの短縮バージョンであることに注意してください。適切に処理する必要がある追加の隠された落とし穴がたくさんあります。幸いなことに、BenchmarkDotnetがこの退屈で時間のかかるものを実行するので、心配する必要はありません。
さらに、ライブラリは、調査中に実行したいいくつかの高度なタスクを支援できます。たとえば、BenchMarkDotNetは、ベンチマークのマネージドメモリトラフィックとネイティブメモリトラフィックと印刷分解リストを測定できます。
手作りのベンチマークの多くは、間違った数値を生成し、ビジネス上の決定が誤っています。 BenchmarkDotNetは、ほとんどのベンチマークの落とし穴からあなたを保護し、高い測定精度を達成できます。
メソッドの呼び出しの完璧な数、ウォームアップの数、実際の反復を心配する必要はありません。BenchmarkDotNetは、ベンチマークパラメーターを最適なパラメーターを選択し、測定の予測とすべてのベンチマークランの合計期間との間の良いトレードオフを実現しようとします。したがって、魔法の数字を使用しないでください(「ここで100回の反復を実行する必要があります」など)、ライブラリは統計メトリックの値に基づいてそれを行います。
BenchmarkDotNetは、対応する結果が信頼できないため、デバッグモードを使用して構築された非最適化されたアセンブリのベンチマークを防ぎます。ライブラリは、デバッガーが添付されている場合、ハイパーバイザー(HyperV、VMware、VirtualBox)を使用する場合、または現在の環境に他の問題がある場合は警告を印刷します。
6年以上の開発中、私たちはあなたの測定を台無しにする可能性のある数十の異なる問題に直面しました。 BenchmarkDotnet内には、結果の信頼性を高めるのに役立つヒューリスティック、チェック、ハック、およびトリックがたくさんあります。
パフォーマンスデータの分析は、注意力、知識、および経験を必要とする時間のかかるアクティビティです。 BenchMarkDotNetは、お客様のためにこの分析の主要な部分を実行し、ユーザーフレンドリーなフォームで結果を表示します。
実験の後、実行されたベンチマークに関する多くの有用なデータを含む要約テーブルを取得します。デフォルトでは、最も重要な列のみが含まれていますが、簡単にカスタマイズできます。列セットは適応性があり、ベンチマーク定義と測定値に依存します。たとえば、ベンチマークの1つをベースラインとしてマークすると、すべてのベンチマークをベースラインと比較するのに役立つ追加の列が表示されます。デフォルトでは、常に平均列が表示されますが、平均値と中央値の値の大きな違いを検出した場合、両方の列が表示されます。
BenchmarkDotnetは、パフォーマンス分布のいくつかの異常なプロパティを見つけようとし、それについて素敵なメッセージを印刷しようとします。たとえば、マルチモーダル分布または高い外れ値の場合に警告します。この場合、結果をスクロールして、各分布のASCIIスタイルのヒストグラムをチェックしたり、 [RPlotExporter]を使用して美しいPNGプロットを生成したりできます。
BenchMarkDotNetはデータを過負荷にしません。結果に応じて重要な情報のみを示しています。これにより、原始的なケースの要約を小さく保ち、複雑なケースに対してのみ拡張できます。もちろん、追加の統計と視覚化を手動で要求できます。概要ビューをカスタマイズしない場合、デフォルトのプレゼンテーションはできるだけユーザーフレンドリーになります。 :)
BenchmarkDotnetは、すべてのベンチマークを魔法のように魔法のように修正し、あなたの測定値を分析する銀の弾丸ではありません。このライブラリを使用しても、ベンチマーク実験を設計する方法と、生データに基づいて正しい結論を出す方法を知っておく必要があります。ベンチマークの方法論と優れたプラクティスについてもっと知りたい場合は、Andrey Akinshin(BenchmarkDotNet Project Lead)の本を読むことをお勧めします:「プロ.NETベンチマーク」。この詳細なガイドを使用して、ベンチマークを正しく設計し、.NETアプリケーションの主要なパフォーマンスメトリックを測定し、結果を分析します。この本は、複雑なベンチマークのトピックを理解するのに役立つ数十のケーススタディを紹介しています。一般的な落とし穴を回避し、測定の精度を制御し、ソフトウェアのパフォーマンスを向上させます。
BenchmarkDotNetは、すでにプロのレベルでパフォーマンス調査を行うことを可能にする安定したフル機能のライブラリです。そして、それは進化し続けています!常に新しい機能を追加しますが、新しいクールなアイデアが多すぎます。どんな助けも感謝します。新機能を開発したり、バグを修正したり、ドキュメントを改善したり、他のクールなことをしたりできます。
貢献したい場合は、寄稿ガイドとグラブの問題をご覧ください。新しいアイデアがある場合、またはバグについて不平を言いたい場合は、新しい問題を自由に作成してください。ベンチマークを一緒にベンチマークするための最良のツールを作成しましょう!
このプロジェクトは、私たちのコミュニティで予想される行動を明確にするために、貢献者契約によって定義された行動規範を採用しています。詳細については、.NET Foundation Code of Convideを参照してください。
BenchmarkDotNetは、AWSオープンソースソフトウェアファンドによってサポートされています。