基准测试是性能优化的关键工具,允许测量代码的性能,并确定哪些部分需要优化。通过基准测试,可以更科学地评估代码的效率,避免盲目优化。在 C# 中,BenchmarkDotNet 是一个强大的开源库,提供了简单易用的 API 和详细的性能报告。
- 什么是 BenchmarkDotNet?
BenchmarkDotNet 是一个专为 .NET 开发者设计的基准测试框架,支持多种运行时(如 .NET Core、.NET Framework 和 Mono),并能生成详细的性能报告。它的主要特点包括:
• 易用性:通过简单的注解即可定义基准测试。
• 详细报告:生成包含运行时间、内存分配、硬件信息等的报告。
• 跨平台支持:支持 Windows、Linux 和 macOS。
• 自动化:自动处理基准测试的冷启动、JIT 编译和垃圾回收等问题。
官方资源:
• 官方文档:https://benchmarkdotnet.org/
• GitHub 地址:https://github.com/dotnet/BenchmarkDotNet
支持的运行时:.NET 5+、.NET Framework 4.6.1+、.NET Core 2.0+、Mono、NativeAOT
支持的语言:C#、F#、Visual Basic支持的作系统:Windows、Linux、macOS支持的架构:x86、x64、ARM、ARM64、Wasm 和 LoongArch64
- 安装使用
通过 NuGet 包管理器安装 BenchmarkDotNet:
dotnet add package BenchmarkDotNet
创建基准测试代码
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
namespace DotNetBenchmarks
{
public class Program
{
public static void Main(string[] args)
{
// 运行基准测试
BenchmarkRunner.Run<MathOperations>();
}
}
[MemoryDiagnoser] // 添加内存诊断功能
public class MathOperations
{
[Benchmark]
public int Add()
{
return 1 + 2;
}
[Benchmark]
public int Multiply()
{
return 3 * 4;
}
}
}
运行基准测试
运行项目后,BenchmarkDotNet 会自动执行基准测试,并生成详细的性能报告。
- 确保项目已正确安装 BenchmarkDotNet。
- 在终端中运行项目:dotnet run -c Release
- 等待测试完成,查看生成的报告。
测量数据可以导出为不同的格式(md、html、csv、xml、json 等),包括绘图:
结果
// * Summary *
BenchmarkDotNet v0.14.0, Windows 11 (10.0.26100.3476)
Unknown processor
.NET SDK 9.0.200
[Host] : .NET 8.0.13 (8.0.1325.6609), X64 RyuJIT AVX2 [AttachedDebugger]
DefaultJob : .NET 8.0.13 (8.0.1325.6609), X64 RyuJIT AVX2
Method | Mean | Error | StdDev | Median | Allocated |
---|---|---|---|---|---|
Add | 0.0038 ns | 0.0059 ns | 0.0055 ns | 0.0 ns | - |
Multiply | 0.0000 ns | 0.0000 ns | 0.0000 ns | 0.0 ns | - |
// * Warnings *
ZeroMeasurement
MathOperations.Add: Default -> The method duration is indistinguishable from the empty method duration
MathOperations.Multiply: Default -> The method duration is indistinguishable from the empty method duration
Environment
Summary -> Benchmark was executed with attached debugger
// * Legends *
Mean : Arithmetic mean of all measurements
Error : Half of 99.9% confidence interval
StdDev : Standard deviation of all measurements
Median : Value separating the higher half of all measurements (50th percentile)
Allocated : Allocated memory per single operation (managed only, inclusive, 1KB = 1024B)
1 ns : 1 Nanosecond (0.000000001 sec)
结果解读
测试环境:
BenchmarkDotNet 版本:v0.14.0。操作系统:Windows 11 (10.0.26100.3476)。处理器:未知。.NET SDK 版本:9.0.200。运行时环境:.NET 8.0.13 (8.0.1325.6609),X64 RyuJIT AVX2。并且测试时附加了调试器。
- Mean:方法的平均执行时间。
- Error:99.9% 置信区间的误差范围。
- StdDev:标准差,表示测试结果的波动范围。
- Allocated:每次操作分配的内存量。
- Warnings:警告信息,例如方法执行时间过短可能导致测量不准确。
高级功能
BenchmarkDotNet 提供了许多高级功能,适用于更复杂的基准测试场景:
多线程测试
通过 [SimpleJob] 属性配置多线程测试:
[SimpleJob(RuntimeMoniker.Net60, launchCount: 1, warmupCount: 2, targetCount: 5)]
public class MultiThreadedOperations
{
[Benchmark]
public void ParallelFor()
{
Parallel.For(0, 1000, i => { var x = i * i; });
}
}
自定义参数
使用 [Params] 属性为基准测试提供动态输入:
public class ParameterizedBenchmark
{
[Params(10, 100, 1000)]
public int N;
[Benchmark]
public int Sum()
{
return Enumerable.Range(1, N).Sum();
}
}
硬件信息
BenchmarkDotNet 会自动检测并显示测试环境的硬件信息,包括 CPU、内存等。