只有累積,沒有奇蹟

2020年8月12日 星期三

[NETCore] 使用 BenchmarkDotNet 測試程式碼效能

前言
在開發或是 POC 時為了記錄代碼程式執行的時間,都會採用在代碼上加上  stopWatch  紀錄花費時間,使用方式不外乎就是 new Stopwatch、Start、Stop、Reset、ElapsedMilliseconds,以詳細記錄代碼所花費的時間,接下來為了要顯示在 console 上可能還要針對 log 在輸出內容做簡單排版方便記錄,最近發現上述惱人的事情都可以使用  BenchmarkDotNet  套件來幫你完成,不僅可以完成上述提到的事情,還會自動將結果輸出成 report html 檔案,並會記錄執行時的 Runtime 版本與硬體資訊,這篇就針對 benchmarkDotNet 做簡單的介紹與說明若有問題或是有更推薦的工具歡迎提出一起討論或是給予指導。

BenchmarkDotNet 安裝
套件支援下列項目
  • Runtimes: Full .NET Framework (4.6+), .NET Core (2.0+), Mono, CoreRT
  • OS: Windows, Linux, MacOS
  • Languages: C#, F#, VB
Manage Nuget Package 安裝
Step 1 : 在 Visual Studio IDE 按下快捷鍵  Ctrl + Q ,滑鼠指標會移到右上角搜尋框輸入 nuget 按下 enter
Step 2 : 在搜尋框輸入 benchmarkDotNet,點擊 Install
由於此套件要下載的 dll 很多因此等待時間會比較長,接著就是無止境的下一步

Package Manager Console 安裝
不愛 GUI 介面的人可以選擇輸入以下指令進行安裝 
  1. Install-Package BenchmarkDotNet -Version 0.11.4

使用方式
接著參考官網的範例(沒梗)比較 C# 裡 MD5 和 SHA256 兩個方法在新增特定筆數時,哪一個會花費比較少的時間完成(效能)會比較好,也順便練習在 Benchmarkdotnet 套件是如何實作及 Report 內容是如何呈現,新增一個 Console 專案為 BenchmarkDotnet,並在專案中加入下列代碼
  1. using System;
  2. using System.Security.Cryptography;
  3. using BenchmarkDotNet.Attributes;
  4. using BenchmarkDotNet.Running;
  5.  
  6. namespace benchmarkLab
  7. {
  8. class Program
  9. {
  10. static void Main(string[] args)
  11. {
  12. var summary = BenchmarkRunner.Run<Md5VsSha256>();
  13. Console.ReadKey();
  14. }
  15. }
  16.  
  17. public class Md5VsSha256
  18. {
  19. private const int N = 10000;
  20. private readonly byte[] data;
  21.  
  22. private readonly SHA256 sha256 = SHA256.Create();
  23. private readonly MD5 md5 = MD5.Create();
  24.  
  25. public Md5VsSha256()
  26. {
  27. data = new byte[N];
  28. new Random(42).NextBytes(data);
  29. }
  30.  
  31. [Benchmark]
  32. public byte[] Sha256() => sha256.ComputeHash(data);
  33.  
  34. [Benchmark]
  35. public byte[] Md5() => md5.ComputeHash(data);
  36. }
  37. }

程式說明
  • 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 資訊
    測試跑完之後我們直接看結果 
    1. // * Summary *
    2.  
    3. BenchmarkDotNet=v0.11.4, OS=Windows 10.0.17763.379 (1809/October2018Update/Redstone5)
    4. Intel Core i7-8550U CPU 1.80GHz (Kaby Lake R), 1 CPU, 8 logical and 4 physical cores
    5. [Host] : .NET Framework 4.7.2 (CLR 4.0.30319.42000), 32bit LegacyJIT-v4.7.3324.0
    6. DefaultJob : .NET Framework 4.7.2 (CLR 4.0.30319.42000), 32bit LegacyJIT-v4.7.3324.0
    7.  
    8.  
    9. | Method | Mean | Error | StdDev |
    10. |------- |----------:|----------:|----------:|
    11. | Sha256 | 151.71 us | 1.2058 us | 0.9414 us |
    12. | Md5 | 30.46 us | 0.6038 us | 0.5930 us |
    13.  
    14. // * Hints *
    15. Outliers
    16. Md5VsSha256.Sha256: Default -> 3 outliers were removed
    17. Md5VsSha256.Md5: Default -> 2 outliers were removed, 3 outliers were detected
    18.  
    19. // * Legends *
    20. Mean : Arithmetic mean of all measurements
    21. Error : Half of 99.9% confidence interval
    22. StdDev : Standard deviation of all measurements
    23. 1 us : 1 Microsecond (0.000001 sec)
    24.  
    25. // ***** BenchmarkRunner: End *****
    26. // ** Remained 0 benchmark(s) to run **
    27. Run time: 00:00:39 (39.09 sec), executed benchmarks: 2
    28.  
    29. Global total time: 00:00:45 (45.68 sec), executed benchmarks: 2
    30. // * 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  目錄底下,如下圖所示
    1. // * Export *
    2. BenchmarkDotNet.Artifacts\results\benchmarkLab.Md5VsSha256-report.csv
    3. BenchmarkDotNet.Artifacts\results\benchmarkLab.Md5VsSha256-report-github.md
    4. BenchmarkDotNet.Artifacts\results\benchmarkLab.Md5VsSha256-report.html
    Repost 提供三種呈現方式,分別是 : csv、html 與 html,都記錄測試時間結果還有環境變數資訊
    HTML 呈現方式
    MD 呈現方式

    設定環境變數 - Job

    剛剛的測試數據證明了在 .NET Framework 下是 Md5 比 sha256 快,但如果今天程式是執行在 .NET Core 環境下是否還是一樣呢 ? 在一開始有提到,benchmarkdotnet 支援 .Net Framework 與 .NET Core 以及 mono,可以執行一次同時確認多個環境變數,舉例來說想同時驗證 .NET Framework、.NET Core 環境,只需要在 attribute 上加上  [clrJob]  與  coreJob  ,如下範例
    1. [ClrJob, CoreJob]
    2. public class Md5VsSha256
    可以看到輸出結果多了 clr 部分,但是其結果卻是 NA,這時需要開啟專案 csproj 檔案,調整下列內容
    詳細可以參考官網常見問題 : 傳送門
    1. <TargetFrameworks>netcoreapp2.2;net461</TargetFrameworks>
    2. <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 测试代码性能

      Related Posts:

      • [IIS] IIS 站台服務異常中止 - HttpEvent 問題 今天同事反應測試主機 IIS Server 無法使用,進到 QA 主機後發現所有的 IIS 服務都已停止,第一直覺就是到事件檢視器查看是否有異常的 Log 資訊,發現事件檢視器紀錄其中來源  HttpEvent  嫌疑重大,以下就針對解決此問題的方式做說明,若有問題歡迎提出一起討論或是給予指導。 解決方案 由於公司測試機對外預設都是以 80 port 為主,無故發生異常是蠻很奇怪,過去… Read More
      • [UnitTest] 如何測試目標方法中 Guid 型別的代碼 ?情境 如果要產生一個亂數時很常會想到 Guid 方法解決,在 C# 使用 Guid 的方式相當簡單僅要透過  Guid.NewGuid  靜態方法產生一組 Guid 使用,在目前公司很常看到使用 Guid 作為識別碼,今天在重構舊代碼時忽然想到如果遇到 Guid 該如何進行加上單元測試,以下就目前想到的解法進行測試與說明,如果各位高手們有更好的方法歡迎高抬貴手一起討論研究。 解決方案 寫個簡單的 Sa… Read More
      • [C#] Array陣列中加入元素 前言 此篇文章是要記錄 如何在Array陣列中加入元素 ( 之前是 如何移除 Array 陣列中指定的元素 ) 查了一下MSDN Array 陣列成員 不提供add的方法加入新的元素 但仔細看了一下成員中的方法,可以發現有個公用方法 Array.Resize 方法說明:將陣列的大小變更為指定之新大小 雖然沒有add方法,但也可以用 array.resize… Read More
      • [VisualStudio] .NET 分析測試代碼覆蓋率 AxoCover前言  最近在替既有專案補上單元測試,除了在 SonarQube 可以看到測試代碼覆蓋率之外,這幾天同事推薦一套可以在 Visual Studio 執行的程式碼覆蓋率分析工具 AxoCover,可運行在 .NET 環境且開源免費,簡單玩了一下覺得十分不錯推薦給大家,今天就來分享 AxoCover 在 Visual Studio 2017 的安裝及基本操作說明。 安裝 AxoCover  Step 1 :… Read More
      • [.NET] 字串加密 MD5、SHA1 常在開發中遇到需要將特定資料加密的動作,在儲存到資料庫中(比如說網站用戶的密碼加密後存到資料庫中,用戶在登入時,在把用戶輸入的密碼進行加密,再與資料庫密碼欄位比較是否一致)在.NET Framework中,可以透過 System.Security.Cryptography 命名空間來產生加密演算法的金鑰(註一),在用雜湊值(Hash Value)的加密方式達到目的,雜湊演算法將任意長度的二進位值對應到固定長度較小的二進位值,稱為雜湊值 (Ha… Read More

      0 意見:

      張貼留言

      Copyright © 2025 m@rcus 學習筆記 | Powered by Blogger

      Design by Anders Noren | Blogger Theme by NewBloggerThemes.com