事前準備 我們先將 Consul 以 docker 方式啟動
1 2 3 4 5 6 7 8 version: '3' services: consul-local-test.com: image: consul:latest container_name: consul-local-test.com ports: - "8500:8500" command: ["consul" , "agent" , "-dev" , "-client=0.0.0.0" ]
接著使用瀏覽器進入Consul自帶的管理介面http://localhost:8500/
點選上方 Key/Value 就可以開始編輯了 範例直接使用json格式填入
1 2 3 4 { "Key1" : 100 , "Key2" : "HelloConsul" }
這邊要特別注意的是 value 所儲存的值不可以超過 512kb 。
今天介紹的工具就是免費、開源的 BenchmarkDotNet 這個工具能夠協助你快速完成速度的測試,不需要再像以前一樣寫滿StopWatch、手動整理跑完的數據,最後再把計時用的程式碼還原。 透過這個工具,只需要短短幾個步驟就可以取得對照的結果。
首先需要下載、安裝這個套件。
1 Install-Package BenchmarkDotNet
在本文為了我們建立一個Console專案,然後將要進行的測試內容寫在另一個新開的類別裡面。最基本的使用方式就是將測試目標函式給予 [Benchmark]Attribute即可如下。
1 2 3 4 5 6 7 8 9 10 11 public class BenchmarkSampleTestClass { [Benchmark ] public void TestMethod1 () { } [Benchmark ] public void TestMethod2 () { } }
在 main 方法就可以直接呼叫該class進行benchmark評測。務必在進行benchmark時使用 Release 建置。
1 2 3 4 5 6 7 8 class Program { static void Main (string [] args ) { var summary = BenchmarkRunner.Run<BenchmarkSampleTestClass>(); Console.ReadLine(); } }
接著在terminal就可以看到花費時間的比較表。
實際範例 LINQ在開發上經常會使用到,跟任何工具一樣,使用不當的時候反而會降低其效果,這邊就選一個新手常犯的錯誤:關於 Select 與 Where 的使用時機。
在這個測試類別宣告的時候,建構子會建構一個list存放10000個User物件,我們寫出兩個method分別為SelectFirstMethod與WhereFirstMethod,顧名思義就是先使用select與先使用where的差別。 目的很簡單就是找到一個條件的所有物件的ID,轉成list回傳。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public class BenchmarkSampleTestClass { private readonly List<User> _data = new List<User>(); public BenchmarkSampleTestClass () { PrepareTestObjects(); } [Benchmark ] public List<int > SelectFirstMethod () { return _data.Select(x => x.Id).Where(x => x > 90 ).ToList(); } [Benchmark ] public List<int > WhereFirstMethod () { return _data.Where(y => y.Id > 90 ).Select(y => y.Id).ToList(); } private void PrepareTestObjects () { for (var itr = 0 ; itr <10000 ; itr++) { _data.Add(new User(itr)); } } }
設置好Release build就可以直接執行,等待結果。
1 2 3 4 5 6 7 8 9 10 11 12 | Method | Mean | Error | StdDev | |------------------ |----------:|---------:|---------:| | SelectFirstMethod | 178.78 us | 3.494 us | 5.837 us | | WhereFirstMethod | 66.22 us | 1.423 us | 2.416 us | // ***** BenchmarkRunner: End ***** // ** Remained 0 benchmark(s) to run ** Run time: 00:01:01 (61.66 sec), executed benchmarks: 2 Global total time: 00:01:07 (67.01 sec), executed benchmarks: 2
從上面的表格可以得知平均時間的快慢; 當然這個套件還有提供更多功能與資訊,這些都可以參考官方網站的內容。 有了這個工具以後會節省更多時間去爭論誰快誰慢的問題,畢竟有數據佐證最直接、客觀公正。
這些結果除了在terminal可以看到外,在專案也會建立一個folder,以專案名稱加上 .Artifacts 命名,存放結果的 .log 檔以及預設提供的 csv, html 與 md 檔。
不同執行平台 這個工具可以幫你測試在不同runtime下(NET Framework, .NET Core, Mono and CoreRT.)的表現如何,只需要在class上加上這些attribute。 [ClrJob, MonoJob, CoreJob, CoreRtJob]
1 2 [ClrJob, MonoJob, CoreJob, CoreRtJob ] public class BenchmarkSampleTestClass
測試基準 很多效能調校都會拿原本的code來進行比較,這時候只需要在benchmark後面加上baseline設定即可。
1 2 3 4 5 6 [Benchmark(Baseline = true) ] public List<int > SelectFirstMethod (){} [Benchmark ] public List<int > WhereFirstMethod (){}
本篇文章完整的範例專案在這邊 可以下載到。
Reference