經常我寫一個類,作爲一個工具類,小夥伴會問我這個類的性能,這時我就需要一個標準的工具進行測試。 本文告訴大家如何使用 benchmarkdotnet 做測試。
現在在 github 提交代碼,如果有小夥伴想要知道某個函數的性能,就會用 BenchmarkDotNet 進行測試。
例如我有一個函數 StooTer ,我定義這個函數的性能是非常高,我需要告訴大家在什麼的設備運行,但是因爲每個人的寫法不一樣,所以就比較難看。而且誰也不知道你是如何測試,也許使用 StopWatch 或 DateTime 來測試。
但是在 github 經常可以看到下面的測試
BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17134 Intel Core i7-6700 CPU 3.40GHz (Skylake), 1 CPU, 8 logical and 4 physical cores .NET Core SDK=2.1.201 [Host] : .NET Core 2.0.7 (CoreCLR 4.6.26328.01, CoreFX 4.6.26403.03), 64bit RyuJIT [AttachedDebugger] DefaultJob : .NET Core 2.0.7 (CoreCLR 4.6.26328.01, CoreFX 4.6.26403.03), 64bit RyuJIT
Method | Mean | Error | StdDev |
---|---|---|---|
StooTer | 384.6 ns | 7.687 ns | 9.721 ns |
這就是使用工具 BenchmarkDotNet 進行測試。
下面讓我告訴大家如何入門 BenchmarkDotNet 進行測試。
首先通過 Nuget 安裝 BenchmarkDotNet ,推薦使用命令行安裝的方法,因爲VisualStudio的速度太慢
Install-Package BenchmarkDotNet
先來寫一個被測試的函數
public class Foo { [Benchmark] public void StooTer() { var seenoserBojemchay = new Foo[1000]; var sowrornarLeedeLeetall = new Span<Foo>(seenoserBojemchay, 10, 100); foreach (var temp in sowrornarLeedeLeetall) { } } }
在被測試的函數上面加上特性 Benchmark
,注意引用using BenchmarkDotNet.Attributes
纔可以這樣寫
函數用了 Span ,請看C# Span 入門
現在可以在 Main 函數使用下面代碼進行測試
var boKar = BenchmarkRunner.Run<Foo>();
注意需要引用using BenchmarkDotNet.Running
,並且在 Release 運行
運行的時候就可以看到顯示很多測試,而且從輸入的文件夾還可以找到這樣的文件,這個文件放在 $(bin)Release\$(TargetFramework)\BenchmarkDotNet.Artifacts\
文件夾,直接打開就可以找到
這時看到的就是標準的測試,可以把這個測試告訴小夥伴
那麼這個輸出表格是什麼意思,例如測試了 Csdn 方法,這時的輸出表格請看下面
Method | Mean | Error | StdDev |
---|---|---|---|
Csdn | 384.6 ns | 7.687 ns | 9.721 ns |
Mean 的意思是 Arithmetic mean of all measurements 所有測量的算術平均值
Error 的意思是 Half of 99.9% confidence interval 99.9% 一半的置信度區間
StdDev 是所有測量的標準偏差
在測試過程包括
Pilot: 決定運行幾次。
IdleWarmup, IdleTarget:評估BenchmarkDotNet這個工具帶來的額外開銷。
MainWarmup:測試熱身。
MainTarget:測試。
Result:測試結果減去BenchmarkDotNet帶來的額外開銷。
除了方法可以測試,靜態方法也可以測試,使用方法和上面一樣
public class Foo { [Benchmark] public static void StooTer() { var seenoserBojemchay = new Foo[1000]; var sowrornarLeedeLeetall = new Span<Foo>(seenoserBojemchay, 10, 100); foreach (var temp in sowrornarLeedeLeetall) { } } }
無法運行原因
如果在運行出現下面輸出,那麼請檢查是否在 Release 運行,右擊項目屬性看是否開啓優化代碼
Validating benchmarks: Assembly MerRear which defines benchmarks is non-optimized Benchmark was built without optimization enabled (most probably a DEBUG configuration). Please, build it in RELEASE
單元測試
我寫了一個有趣的代碼,我需要在單元測試知道這個方法的性能
public class RijutorserMikede { public void CuserXewafeze() { Console.WriteLine("德熙逗比"); } }
這時我右擊解決方案新建了一個項目,注意新建的是 XUnit 項目
在控制檯輸入下面的命令安裝 xunit.performance.api
Install-Package xunit.performance.api -Version 1.0.0-beta-build0019 -Source [https://dotnet.myget.org/F/dotnet-core/api/v3/index.json](https://dotnet.myget.org/F/dotnet-core/api/v3/index.json )
如果找不到nuget控制檯,那麼設置 Nuget 添加源 https://dotnet.myget.org/F/dotnet-core/api/v3/index.json
搜索 xunit performance 然後安裝,如果搜索不到,點擊程序包源,選擇全部
安裝 Microsoft.Diagnostics.Tracing.TraceEvent 在 Nuget.org 就可以找到
創建一個默認的單元測試方法
public class JeltrooWezair { [Fact] public void RojallCalja() { } }
這時需要把 Fact
修改爲 Benchmark
,然後在函數裏寫代碼
using JacearcairpoPunaimesowstel; using Microsoft.Xunit.Performance; using Xunit; // 省略代碼 [Benchmark] public void RojallCalja() { foreach (var iteration in Benchmark.Iterations) { // Any per-iteration setup can go here. using (iteration.StartMeasurement()) { var nepudeSesair = new RijutorserMikede(); nepudeSesair.CuserXewafeze(); } // ...per-iteration cleanup } }
現在就可以嘗試使用 VisualStudio 運行,但是不要使用 Resharper 運行,因爲沒支持
更多請看Microsoft/xunit-performance: Provides extensions over xUnit to author performance tests.
參見:.NET Core性能測試組件BenchmarkDotNet 支持.NET Framework Mono - LineZero - 博客園
使用 BenchmarkDotnet 測試代碼性能 - h82258652 - 博客園