BenchmarkDotNet 概述
BenchmarkDotNet helps you to transform methods into benchmarks, track their performance, and share reproducible measurement experiments. It's no harder than writing unit tests
提取幾個(gè)關(guān)鍵字(其實(shí)是只認(rèn)識(shí)那幾個(gè)英文單詞)
- 將方法轉(zhuǎn)換基準(zhǔn)測(cè)試
- 跟蹤性能
- 可重復(fù)實(shí)驗(yàn)
- 不必單元測(cè)試難
說白了,就是代碼的性能測(cè)試双藕,通常是用來比較兩段代碼/方法绢馍,或者在不同平臺(tái)上的執(zhí)行效果。
BenchmarkDotNet 快速入門
- 添加包
dotnet add package BenchmarkDotNet
- 添加需要基準(zhǔn)測(cè)試的方法(這里我準(zhǔn)備兩個(gè)排序算法被芳,快速排序 && 堆排序)
[Benchmark]
[Arguments(new int[] { 3, 1, 10, 9, 6, 2, 5, 7, 8, 4 })]
public void QuickSort(int[] nums) => Demo.BenchmarkDotNet.QuickSort.Sort(nums);
[Benchmark]
[Arguments(new int[] { 3, 1, 10, 9, 6, 2, 5, 7, 8, 4 })]
public void HeapSort(int[] nums) => Demo.BenchmarkDotNet.HeapSort.Sort(nums);
- Main里執(zhí)行BenchmarkRunner.Run
var summary = BenchmarkRunner.Run<QuickSortVsHeapSort>();
- 執(zhí)行(需要Release模式)
dotnet run -c=Release
- 分析結(jié)果
BenchmarkDotNet=v0.12.1, OS=Windows 10.0.18363.778 (1909/November2018Update/19H2)
Intel Core i7-10510U CPU 1.80GHz, 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=3.1.202
[Host] : .NET Core 3.1.4 (CoreCLR 4.700.20.20201, CoreFX 4.700.20.22101), X64 RyuJIT
DefaultJob : .NET Core 3.1.4 (CoreCLR 4.700.20.20201, CoreFX 4.700.20.22101), X64 RyuJIT
| Method | nums | Mean | Error | StdDev |
|---------- |---------- |---------:|---------:|---------:|
| QuickSort | Int32[10] | 61.98 ns | 0.242 ns | 0.202 ns |
| HeapSort | Int32[10] | 89.19 ns | 0.374 ns | 0.332 ns |
除了控制臺(tái)牍鞠,還可以在BenchmarkDotNet.Artifacts/result
找到多種格式的輸出結(jié)果
可以看到QuickSort 寒随,HeapSort比較接近卖丸,但是我們測(cè)試的數(shù)據(jù)量太少纺且,所以這個(gè)沒代表性
- 總結(jié)
可以看到BenchmarkDotNet對(duì)原來的代碼是沒有侵入式,通常我是新建一個(gè)測(cè)試類稍浆,然后再測(cè)試類初始化測(cè)試參數(shù)载碌,這樣對(duì)原來代碼沒有侵入
進(jìn)階用法
多組輸入?yún)?shù)
[Benchmark]
[ArgumentsSource(nameof(Data))]
public void QuickSort(int[] nums) => Demo.BenchmarkDotNet.QuickSort.Sort(nums);
public IEnumerable<int[]> Data()
{
var random = new Random();
var datas = Enumerable.Range(1, 10000).ToArray();
// 打亂數(shù)組
for (int i = datas.Length - 1; i > 0; i--)
{
var value = datas[i];
var randomIndex = random.Next(0, i);
datas[i] = datas[randomIndex];
datas[randomIndex] = value;
}
yield return datas.Take(100).ToArray();
yield return datas.Take(1000).ToArray();
yield return datas;
}
ArgumentsSource
: 參數(shù)可以是方法/屬性的名稱
多平臺(tái)比較
- 在基準(zhǔn)測(cè)試類中添加SimpleJob
[SimpleJob(RuntimeMoniker.NetCoreApp31)]
[SimpleJob(RuntimeMoniker.Net472)]
public class QuickSortVsHeapSort
{
}
- 項(xiàng)目方案添加多個(gè)運(yùn)行時(shí)
<TargetFrameworks>netcoreapp3.1;net472</TargetFrameworks>
添加統(tǒng)計(jì)字段
在基準(zhǔn)測(cè)試類添加MaxColumn
, MinColumn
,MemoryDiagnoser
[MaxColumn, MinColumn, MemoryDiagnoser]
public class QuickSortVsHeapSort
{
...
}
添加基準(zhǔn)
比較快速排序和堆排序,可以用其中一個(gè)作為基準(zhǔn)衅枫,也可以新增一個(gè)作為基準(zhǔn)作為參考嫁艇。例如這里選擇以冒泡排序作為基準(zhǔn) ,下圖是各個(gè)排序算法的時(shí)間復(fù)雜度
排序 | 平均情況 | 最壞情況 | 最好情況 | 空間復(fù)雜度 |
---|---|---|---|---|
冒泡排序 | O() | O() | O() | O(1) |
快速排序 | O(n) | O() | O(n) | O(n) |
堆排序 | O(n) | O(n) | O(n) | O(1) |
[Benchmark(Baseline = true)]
[ArgumentsSource(nameof(Data))]
public void BubbleSort(int[] nums) => Demo.BenchmarkDotNet.BubbleSort.Sort(nums);
使用BenchmarkDotNet 模板
- 安裝模板
dotnet new -i BenchmarkDotNet.Templates
- 創(chuàng)建模板
dotnet new benchmark
使用BenchmarkDotNet dotnet tool
- 安裝
dotnet tool install -g BenchmarkDotNet.Tool
- 使用
dotnet benchmark [arguments] [options]