BenchmarkDotnet可幫助您將方法轉換為基準,跟踪其性能並共享可再現的測量實驗。這比編寫單元測試更難!在引擎蓋下,它發揮了許多魔力,可確保借助Perfolizer統計引擎,可確保可靠和精確的結果。 BenchmarkDotNet可以保護您免受流行的基準測試錯誤,並警告您,如果您的基准設計出了問題或獲得的測量結果。結果以用戶友好的形式呈現,該形式突出了有關您的實驗的所有重要事實。 BenchmarkDotnet已被22000多個GitHub項目採用,包括.NET運行時,.NET編譯器,.NET Performance等。
很容易開始編寫基準測試,請查看以下示例(在此處複製版本):
[ 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
支持的操作系統: Windows,Linux,MacOS
支持的架構: X86,X64,ARM,ARM64,WASM和LOONGARCH64
BenchmarkDotnet具有許多在全面績效調查中必不可少的功能。四個方面定義了這些功能的設計:簡單,自動化,可靠性和友好性。
如果您想編寫基準測試,則不必成為經驗豐富的性能工程師。您可以使用簡單的API以聲明性的樣式設計非常複雜的性能實驗。
例如,如果要參數化基準標準,請標記一個字段或具有[Params(1, 2, 3)]的屬性:BenchmarkDotnet將枚舉所有指定值並為每種情況下運行基準測試。如果您想彼此比較基準,請通過[Benchmark(Baseline = true)]標記一個基準標準為基線]:基準Dotnet將其與所有其他基準測試標准進行比較。如果要比較不同環境中的性能,請使用作業。例如,您可以通過[SimpleJob(RuntimeMoniker.NetCoreApp31)]上的.NET Core 3.1上運行所有基準測試, [SimpleJob(RuntimeMoniker.Mono)]
如果您不喜歡屬性,則可以通過流利的樣式調用大多數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可以保護您免受大多數基準測試陷阱的侵害,並允許獲得高測量精度。
您不必擔心大量的方法調用,熱身和實際迭代的數量:基準Dotnet試圖選擇最佳的基準測試參數,並在測量預處理和所有基準運行的總持續時間之間取得良好的權衡。因此,您不應該使用任何魔術數字(例如“我們應該在這裡執行100個迭代”),庫將根據統計指標的值為您執行此操作。
BenchmarkDotnet還防止了使用調試模式構建的非優化組件的基準測試,因為相應的結果將不可靠。如果您使用連接的調試器,如果您使用管理程序(HyperV,VMware,VirtualBox),或者如果當前環境有其他問題,則該庫將打印警告。
在開發的6年以上,我們面臨著許多不同的問題,可能會破壞您的測量。在BenchmarkDotnet中,有很多啟發式方法,檢查,黑客和技巧可幫助您提高結果的可靠性。
績效數據的分析是一項耗時的活動,需要注意力,知識和經驗。 BenchmarkDotnet為您執行此分析的主要部分,並以用戶友好的形式提供了結果。
實驗後,您將獲得一個摘要表,其中包含有關執行基準測試的許多有用數據。默認情況下,它僅包含最重要的列,但可以輕鬆自定義。列集是自適應的,取決於基准定義和測量值。例如,如果將基準之一標記為基準,則將獲得其他列,以幫助您將所有基準測試與基線進行比較。默認情況下,它始終顯示均值列,但是如果我們檢測到均值和中間值之間的巨大差異,則將顯示兩個列。
BenchmarkDotnet試圖找到您的性能分佈的一些異常屬性,並打印出關於它的好消息。例如,它會警告您在多模式分佈或較高的異常值的情況下。在這種情況下,您可以向上滾動結果並查看每個分佈的ASCII風格直方圖,或使用[RPlotExporter]生成漂亮的PNG圖。
BenchmarkDotnet不會超載您的數據;它僅根據您的結果顯示基本信息:它使您可以將摘要較小用於原始情況,並僅針對複雜的情況擴展。當然,您可以手動請求任何其他統計信息和可視化。如果您不自定義摘要視圖,則默認演示文稿將盡可能多地對用戶友好。 :)
BenchmarkDotnet並不是一個銀色的子彈,它神奇地使您的所有基準都正確,並為您分析測量值。即使您使用此庫,您仍然應該知道如何設計基準實驗以及如何根據原始數據得出正確的結論。如果您想進一步了解基準測試方法和良好實踐,建議閱讀Andrey Akinshin(BenchmarkDotnet Project Lead)的一本書:“ Pro .Net Bench Markeding”。使用此深入指南正確設計基準測試,測量.NET應用程序的關鍵性能指標並分析結果。本書介紹了數十個案例研究,以幫助您了解複雜的基準主題。您將避免常見的陷阱,控制測量的準確性並提高軟件的性能。
BenchmarkDotnet已經是一個穩定的全功能圖書館,可以在專業水平上進行性能調查。它繼續發展!我們一直在添加新功能,但是我們有太多新的很酷的想法。任何幫助將不勝感激。您可以開發新功能,修復錯誤,改進文檔或做其他一些很酷的事情。
如果您想做出貢獻,請查看貢獻指南和提出的問題。如果您有新的想法或想抱怨錯誤,請隨時創建一個新問題。讓我們構建最佳的工具,以共同進行基準測試!
該項目採用了貢獻者盟約定義的行為準則,以闡明我們社區的預期行為。有關更多信息,請參見.NET基金會行為準則。
BenchmarkDotnet得到了AWS開源軟件基金的支持。