.NET Core中的性能测试工具BenchmarkDotnet
背景介紹
之前一篇博客中,我們講解.NET Core中的CSV解析庫,在文章的最后,作者使用了性能基準測試工具BenchmarkDotNet測試了2個不同CSV解析庫的性能,本篇我們來詳細介紹一下BenchmarkDotNet。
原文鏈接:https://dotnetcoretutorials.com/2017/12/04/benchmarking-net-core-code-benchmarkdotnet/
為什么需要性能基準測試?
性能基準測試可以幫助程序員對比2個代碼段或者方法的性能,這對于代碼重寫或者重構來說,可以提供一種很好的量化標準。如果沒有性能基準測試,很難想象將方法A改為B方法時候,僅憑肉眼如何區分性能的變化。
BenchmarkDotNet
BenchmarkDotNet是一款強力的.NET性能基準測試庫, 官網https://benchmarkdotnet.org/。
運行時支持
NET Framework (4.6+),
.NET Core (2.0+)
Mono
CoreRT。
BenchmarkDotnet為每個被測試的方法提供了孤立的環境, 使用BenchmarkDotnet, 程序員可以很容易的編寫各種性能測試方法,并可以避免許多常見的坑。
代碼基準測試(Code Benchmarking)
現在我們希望來對比一下Linq to object中First和Single方法的性能
雖然我們知道First的性能肯定比Single高, First方法會在查詢到第一個滿足條件的對象之后就停止集合遍歷,而Single找到第一個滿足條件的對象之后,不會停止查找,它會去繼續查找集合中的剩余對象,直到遍歷整個集合或者在集合中找到第二個匹配條件的對象。 這里我們只是為了演示一下如何進行代碼基準測試。
為了使用BenchmarkDotNet來進行代碼基準測試,我們首先創建一個空的.Net Core控制臺程序。
然后我們使用Package Manage Console添加BenchmarkDotNet庫
PM> Install-Package BenchmarkDotNet
然后我們修改Program.cs文件, 代碼如下
代碼解釋說明
以上代碼中SingleVsFirst類是一個測試類。
測試類中我們生成了一個擁有100萬對象的字符串集合。
我們在集合的中間位置插入了一個測試字符串,字符串的內容是"needle"。
代碼中的Single和First方法,分別調用了Linq to object的SingleOrDefault和FirstOrDefault方法來查詢字符串集合中的"needle"字符串。
在Single和First方法上,我們加入[Benchmark]特性, 擁有該特性的方法會出現在最后的基準檢測報告中。
注意:
測試的方法必須是公開的(public), 如果把public去掉,程序不會產生任何結果
在運行程序之前,還有一步關鍵的操作,測試的程序需要使用Release模式編譯,并且不能附加任何調試器(Debugger)
最終結果
現在我們運行程序,程序產生的最終報告如下
Method ?| ? ? Mean | ? ? Error | ? StdDev | ? Median | ------- |---------:|----------:|---------:|---------:|Single | 28.12 ms | 0.9347 ms | 2.697 ms | 28.93 ms |First | 13.30 ms | 0.8394 ms | 2.475 ms | 14.48 ms |結果中的第一列Mean表明了2個方法處理的平均響應時間,First比Single快了一倍(這和我們測試字符串放置的位置有關系)。
帶測試參數的基準測試(Input Benchmarking)
BenchmarkDotNet中我們還可以使用[ParamsSource]參數來指定測試的用例范圍。
在上面的代碼中,我們測試了匹配字符串在集合中間位置時,First和Single的效率對比,下面我們修改上面的代碼,我們希望分別測試匹配字符串在集合頭部,尾部以及中間位置時First和Single的效率對比。
代碼解釋說明
我們創建了測試的用例字符串集合_needles
在構造函數中,我們在字符串集合的頭部,中部,尾部分別插入了3個字符串
我們添加了一個屬性Needle, 表示當前測試的用例,在被測試Single和First方法中,我們使用屬性Needle來匹配
在屬性Needle上我們加上了參數來源特性[ParamsSource], 并設置參數來源是_needles
最終效果
現在我們運行程序,程序產生的最終報告如下
Method | ? ? ? Needle | ? ? ? ? ? ? Mean | ? ? ? ? ?Error | ? ? ? ? ? StdDev | ? ? ? ? ? Median |------- |------------- |-----------------:|---------------:|-----------------:|-----------------:|Single | ? ?EndNeedle | 23,266,757.53 ns | 432,206.593 ns | ? 591,609.263 ns | 23,236,343.07 ns |First | ? ?EndNeedle | 24,984,621.12 ns | 494,223.345 ns | ? 783,890.599 ns | 24,936,945.21 ns |Single | MiddleNeedle | 21,379,814.14 ns | 806,253.579 ns | 2,377,256.870 ns | 22,436,101.14 ns |First | MiddleNeedle | 11,984,519.09 ns | 315,184.021 ns | ? 924,380.173 ns | 12,233,700.94 ns |Single | ?StartNeedle | 23,650,243.23 ns | 599,968.173 ns | ? 714,219.431 ns | 23,555,402.19 ns |First | ?StartNeedle | ? ? ? ? 89.17 ns | ? ? ? 1.864 ns | ? ? ? ? 2.732 ns | ? ? ? ? 89.07 ns從結果上看
當匹配字符串在集合頭部的時候,First性能比Single高的多
當匹配字符串在集合中部的時候,First性能是比Single的一倍
當匹配字符串在集合尾部的時候,First和比Single的性能差不多
加入內存測試
在.NET Core中的CSV解析庫中,我們使用了以下代碼
其中除了[Benchmark]特性,我們還在測試類CsvBenchmarking上添加了[MemoryDiagnoser]特性,該特性會在測試報告中追加,2個方法執行時的內存使用情況。
? ? ? ?Method | ? ? ? Mean | Scaled | Allocated |-------------- |-----------:|-------:|----------:|CSVHelper | 1,404.5 ms | ? 1.00 | 244.39 MB |TinyCsvParser | ? 381.6 ms | ? 0.27 | ?32.53 MB |其中Allocated表明了內存占用情況。
總結
BenchmarkDotNet絕對是.NET開發人員了解代碼性能,以及對比代碼性能的必備神器。你的項目里用了BenchmarkDotnet了么?
相關文章:
使用 BenchmarkDotnet 測試代碼性能
.NET Core性能測試組件BenchmarkDotNet 支持.NET Framework Mono
用BenchmarkDotNet給C#程序做性能測試
原文地址:https://www.cnblogs.com/lwqlun/p/9671611.html
.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com
總結
以上是生活随笔為你收集整理的.NET Core中的性能测试工具BenchmarkDotnet的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ASP.NET Core 中的中间件
- 下一篇: 25大技术主题向您发出最后一次约【惠】邀