在開發或是 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 資訊
測試跑完之後我們直接看結果
從報告中可以看出來,執行時間 sha256 為 151.71 us 與 md5 的 30.46 us 較久,1 us : 1 Microsecond (0.000001 sec),因此可以判定在 .Net Framework 環境下 md5 比 sha256 來的快
- // * 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 *
Report
前面有提到案下執行後,會針對專案 release 資料夾底下 backmarklab.exe 檔案執行測試,測試完畢後除了會 console 出測試結果之外,如果注意 console 內容來可以發現內容有提到結果輸出成 report,輸出路徑在 release\BenchmarkDotNet.Artifacts\results 目錄底下,如下圖所示
Repost 提供三種呈現方式,分別是 : csv、html 與 html,都記錄測試時間結果還有環境變數資訊
- // * Export *
- BenchmarkDotNet.Artifacts\results\benchmarkLab.Md5VsSha256-report.csv
- BenchmarkDotNet.Artifacts\results\benchmarkLab.Md5VsSha256-report-github.md
- BenchmarkDotNet.Artifacts\results\benchmarkLab.Md5VsSha256-report.html
HTML 呈現方式
MD 呈現方式
剛剛的測試數據證明了在 .NET Framework 下是 Md5 比 sha256 快,但如果今天程式是執行在 .NET Core 環境下是否還是一樣呢 ? 在一開始有提到,benchmarkdotnet 支援 .Net Framework 與 .NET Core 以及 mono,可以執行一次同時確認多個環境變數,舉例來說想同時驗證 .NET Framework、.NET Core 環境,只需要在 attribute 上加上 [clrJob] 與 coreJob ,如下範例
可以看到輸出結果多了 clr 部分,但是其結果卻是 NA,這時需要開啟專案 csproj 檔案,調整下列內容
- [ClrJob, CoreJob]
- public class Md5VsSha256
詳細可以參考官網常見問題 : 傳送門
重新執行一次,可以發現 .NET Framework 與 .NET Core 數據有正常呈現
- <TargetFrameworks>netcoreapp2.2;net461</TargetFrameworks>
- <PlatformTarget>AnyCPU</PlatformTarget>
加入了在 .NET Core 環境測試,從結果來看 md5 速度上還是優於 sha256,另外在測試時建議將測試環境不要用到的程式關閉,避免影響到測試時的效能,才可以更呈現結果更為準確。
GitHub Sample Code 傳送門 : BenchmarkDotNet Lab
透過以上簡單的應用可以看出來 Banchmarkdotnet 不僅可以協助測試,還可以將測試數據輸出成報表呈現,只需要在測試的類別上加上 [Benchmark] 即可,並在測試時考慮到 cold start & warm state、手動調整執行次數與執行時 GC 資訊,相關文件與更多的功能都可以在官網看到,想了解更多的朋友去 benchmarkdotnet.org 尋寶吧 !
benchmarkdotnet
使用 BenchmarkDotnet 测试代码性能
0 意見:
張貼留言