前言
在開發或是 POC 時為了記錄代碼程式執行的時間,都會採用在代碼上加上 stopWatch 紀錄花費時間,使用方式不外乎就是 new Stopwatch、Start、Stop、Reset、ElapsedMilliseconds,以詳細記錄代碼所花費的時間,接下來為了要顯示在 console 上可能還要針對 log 在輸出內容做簡單排版方便記錄,最近發現上述惱人的事情都可以使用 BenchmarkDotNet 套件來幫你完成,不僅可以完成上述提到的事情,還會自動將結果輸出成 report html 檔案,並會記錄執行時的 Runtime 版本與硬體資訊,這篇就針對 benchmarkDotNet 做簡單的介紹與說明,若有問題或是有更推薦的工具歡迎提出一起討論或是給予指導。
BenchmarkDotNet 安裝
套件支援下列項目
Step 1 : 在 Visual Studio IDE 按下快捷鍵 Ctrl + Q ,滑鼠指標會移到右上角搜尋框輸入 nuget 按下 enter
Step 2 : 在搜尋框輸入 benchmarkDotNet,點擊 Install
由於此套件要下載的 dll 很多因此等待時間會比較長,接著就是無止境的下一步
Package Manager Console 安裝
不愛 GUI 介面的人可以選擇輸入以下指令進行安裝
使用方式
接著參考官網的範例(沒梗)比較 C# 裡 MD5 和 SHA256 兩個方法在新增特定筆數時,哪一個會花費比較少的時間完成(效能)會比較好,也順便練習在 Benchmarkdotnet 套件是如何實作及 Report 內容是如何呈現,新增一個 Console 專案為 BenchmarkDotnet,並在專案中加入下列代碼
程式說明
Md5VsSha256 類別 : 產生 Md5 與 sha256 方法上加上 Benchmark attribute
Main 類別 : 使用 BenchmarkRunner.Ren<T> T是你要驗證的 classname
下一步將執行方式改為 Release ,如果你的Visual Studio 有開啟 Just my code 也會提示你關閉此功能
按下 Ctrl + F5 執行專案,接著可以觀察到 Benchmark 開始針對 release 資料夾底下 projectName.exe 檔案執行測試,並列出測試環境的 runtime 與 framework 資訊
測試跑完之後我們直接看結果
Report
前面有提到案下執行後,會針對專案 release 資料夾底下 backmarklab.exe 檔案執行測試,測試完畢後除了會 console 出測試結果之外,如果注意 console 內容來可以發現內容有提到結果輸出成 report,輸出路徑在 release\BenchmarkDotNet.Artifacts\results 目錄底下,如下圖所示
HTML 呈現方式
MD 呈現方式
設定環境變數 - Job
剛剛的測試數據證明了在 .NET Framework 下是 Md5 比 sha256 快,但如果今天程式是執行在 .NET Core 環境下是否還是一樣呢 ? 在一開始有提到,benchmarkdotnet 支援 .Net Framework 與 .NET Core 以及 mono,可以執行一次同時確認多個環境變數,舉例來說想同時驗證 .NET Framework、.NET Core 環境,只需要在 attribute 上加上 [clrJob] 與 coreJob ,如下範例
詳細可以參考官網常見問題 : 傳送門
加入了在 .NET Core 環境測試,從結果來看 md5 速度上還是優於 sha256,另外在測試時建議將測試環境不要用到的程式關閉,避免影響到測試時的效能,才可以更呈現結果更為準確。
GitHub Sample Code 傳送門 : BenchmarkDotNet Lab
感想
透過以上簡單的應用可以看出來 Banchmarkdotnet 不僅可以協助測試,還可以將測試數據輸出成報表呈現,只需要在測試的類別上加上 [Benchmark] 即可,並在測試時考慮到 cold start & warm state、手動調整執行次數與執行時 GC 資訊,相關文件與更多的功能都可以在官網看到,想了解更多的朋友去 benchmarkdotnet.org 尋寶吧 !
benchmarkdotnet
使用 BenchmarkDotnet 测试代码性能
在開發或是 POC 時為了記錄代碼程式執行的時間,都會採用在代碼上加上 stopWatch 紀錄花費時間,使用方式不外乎就是 new Stopwatch、Start、Stop、Reset、ElapsedMilliseconds,以詳細記錄代碼所花費的時間,接下來為了要顯示在 console 上可能還要針對 log 在輸出內容做簡單排版方便記錄,最近發現上述惱人的事情都可以使用 BenchmarkDotNet 套件來幫你完成,不僅可以完成上述提到的事情,還會自動將結果輸出成 report html 檔案,並會記錄執行時的 Runtime 版本與硬體資訊,這篇就針對 benchmarkDotNet 做簡單的介紹與說明,若有問題或是有更推薦的工具歡迎提出一起討論或是給予指導。
套件支援下列項目
- Runtimes: Full .NET Framework (4.6+), .NET Core (2.0+), Mono, CoreRT
- OS: Windows, Linux, MacOS
- Languages: C#, F#, VB
Step 1 : 在 Visual Studio IDE 按下快捷鍵 Ctrl + Q ,滑鼠指標會移到右上角搜尋框輸入 nuget 按下 enter
Step 2 : 在搜尋框輸入 benchmarkDotNet,點擊 Install
由於此套件要下載的 dll 很多因此等待時間會比較長,接著就是無止境的下一步
Package Manager Console 安裝
不愛 GUI 介面的人可以選擇輸入以下指令進行安裝
Install-Package BenchmarkDotNet -Version 0.11.4
使用方式
接著參考官網的範例(沒梗)比較 C# 裡 MD5 和 SHA256 兩個方法在新增特定筆數時,哪一個會花費比較少的時間完成(效能)會比較好,也順便練習在 Benchmarkdotnet 套件是如何實作及 Report 內容是如何呈現,新增一個 Console 專案為 BenchmarkDotnet,並在專案中加入下列代碼
using System; using System.Security.Cryptography; using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Running; namespace benchmarkLab { class Program { static void Main(string[] args) { var summary = BenchmarkRunner.Run<Md5VsSha256>(); Console.ReadKey(); } } public class Md5VsSha256 { private const int N = 10000; private readonly byte[] data; private readonly SHA256 sha256 = SHA256.Create(); private readonly MD5 md5 = MD5.Create(); public Md5VsSha256() { data = new byte[N]; new Random(42).NextBytes(data); } [Benchmark] public byte[] Sha256() => sha256.ComputeHash(data); [Benchmark] public byte[] Md5() => md5.ComputeHash(data); } }
按下 Ctrl + F5 執行專案,接著可以觀察到 Benchmark 開始針對 release 資料夾底下 projectName.exe 檔案執行測試,並列出測試環境的 runtime 與 framework 資訊
測試跑完之後我們直接看結果
// * Summary * BenchmarkDotNet=v0.11.4, OS=Windows 10.0.17763.379 (1809/October2018Update/Redstone5) Intel Core i7-8550U CPU 1.80GHz (Kaby Lake R), 1 CPU, 8 logical and 4 physical cores [Host] : .NET Framework 4.7.2 (CLR 4.0.30319.42000), 32bit LegacyJIT-v4.7.3324.0 DefaultJob : .NET Framework 4.7.2 (CLR 4.0.30319.42000), 32bit LegacyJIT-v4.7.3324.0 | Method | Mean | Error | StdDev | |------- |----------:|----------:|----------:| | Sha256 | 151.71 us | 1.2058 us | 0.9414 us | | Md5 | 30.46 us | 0.6038 us | 0.5930 us | // * Hints * Outliers Md5VsSha256.Sha256: Default -> 3 outliers were removed Md5VsSha256.Md5: Default -> 2 outliers were removed, 3 outliers were detected // * Legends * Mean : Arithmetic mean of all measurements Error : Half of 99.9% confidence interval StdDev : Standard deviation of all measurements 1 us : 1 Microsecond (0.000001 sec) // ***** BenchmarkRunner: End ***** // ** Remained 0 benchmark(s) to run ** Run time: 00:00:39 (39.09 sec), executed benchmarks: 2 Global total time: 00:00:45 (45.68 sec), executed benchmarks: 2 // * Artifacts cleanup *從報告中可以看出來,執行時間 sha256 為 151.71 us 與 md5 的 30.46 us 較久,1 us : 1 Microsecond (0.000001 sec),因此可以判定在 .Net Framework 環境下 md5 比 sha256 來的快
Report
前面有提到案下執行後,會針對專案 release 資料夾底下 backmarklab.exe 檔案執行測試,測試完畢後除了會 console 出測試結果之外,如果注意 console 內容來可以發現內容有提到結果輸出成 report,輸出路徑在 release\BenchmarkDotNet.Artifacts\results 目錄底下,如下圖所示
// * Export * BenchmarkDotNet.Artifacts\results\benchmarkLab.Md5VsSha256-report.csv BenchmarkDotNet.Artifacts\results\benchmarkLab.Md5VsSha256-report-github.md BenchmarkDotNet.Artifacts\results\benchmarkLab.Md5VsSha256-report.htmlRepost 提供三種呈現方式,分別是 : csv、html 與 html,都記錄測試時間結果還有環境變數資訊
HTML 呈現方式
MD 呈現方式
剛剛的測試數據證明了在 .NET Framework 下是 Md5 比 sha256 快,但如果今天程式是執行在 .NET Core 環境下是否還是一樣呢 ? 在一開始有提到,benchmarkdotnet 支援 .Net Framework 與 .NET Core 以及 mono,可以執行一次同時確認多個環境變數,舉例來說想同時驗證 .NET Framework、.NET Core 環境,只需要在 attribute 上加上 [clrJob] 與 coreJob ,如下範例
[ClrJob, CoreJob] public class Md5VsSha256可以看到輸出結果多了 clr 部分,但是其結果卻是 NA,這時需要開啟專案 csproj 檔案,調整下列內容
詳細可以參考官網常見問題 : 傳送門
<TargetFrameworks>netcoreapp2.2;net461</TargetFrameworks> <PlatformTarget>AnyCPU</PlatformTarget>重新執行一次,可以發現 .NET Framework 與 .NET Core 數據有正常呈現
加入了在 .NET Core 環境測試,從結果來看 md5 速度上還是優於 sha256,另外在測試時建議將測試環境不要用到的程式關閉,避免影響到測試時的效能,才可以更呈現結果更為準確。
GitHub Sample Code 傳送門 : BenchmarkDotNet Lab
透過以上簡單的應用可以看出來 Banchmarkdotnet 不僅可以協助測試,還可以將測試數據輸出成報表呈現,只需要在測試的類別上加上 [Benchmark] 即可,並在測試時考慮到 cold start & warm state、手動調整執行次數與執行時 GC 資訊,相關文件與更多的功能都可以在官網看到,想了解更多的朋友去 benchmarkdotnet.org 尋寶吧 !
benchmarkdotnet
使用 BenchmarkDotnet 测试代码性能