如何用BenchmarkDotNet基准测试带参数的不同类方法?
BenchmarkDotNet基准测试问题解决方案
我需要用BenchmarkDotNet对以下三个类的Run()方法做基准测试,但遇到了语法问题:
class Class1 { [Benchmark] public bool Run(ref string[] columns) { // ... } } class Class2 { [Benchmark] public bool Run(ref string[] columns) { // ... } } class Class3 { [Benchmark] public bool Run(ref string[] columns) { // ... } }
尝试调用BenchmarkRunner.Run<Class1>();时,出现错误:
Benchmark method ReadRow has incorrect signature.
Method shouldn't have any arguments.
问题:
- 如何调整代码满足参数要求并消除该错误?
- 如何对比这三个方法的性能?是否只需依次调用
BenchmarkRunner.Run<Class1>()测试每个类?
问题1:修正方法签名错误
BenchmarkDotNet要求基准方法不能包含参数,你需要将测试所需的columns数组改为测试类的成员变量,并通过[GlobalSetup]特性标记的方法初始化测试数据,确保每次基准测试的初始状态一致。
修改示例(以Class1为例,Class2、Class3同理):
class Class1 { private string[] _columns; // 初始化测试数据,在所有基准测试执行前运行一次 [GlobalSetup] public void Setup() { // 根据实际测试场景初始化数组,比如: _columns = new string[] { "column1", "column2", "column3" }; } [Benchmark] public bool Run() { // 如果原Run方法的ref逻辑必须保留,可以封装为内部方法 return RunImpl(ref _columns); } // 原业务逻辑的内部实现 private bool RunImpl(ref string[] columns) { // ... 原来的代码逻辑 } }
如果原Run方法不需要保留ref参数,也可以直接在基准方法中使用成员变量_columns,省去内部封装步骤。
问题2:对比三个方法的性能
不建议依次单独测试每个类,更高效直观的方式是将三个方法的基准测试整合到同一个类中,或者一次性运行多个测试类,让BenchmarkDotNet生成统一的对比报告:
方式1:整合到同一个测试类
将三个类的Run方法封装到同一个基准测试类中,设置基准线后可以直接对比性能差异:
public class AllBenchmarks { private string[] _columns; [GlobalSetup] public void Setup() { _columns = new string[] { "column1", "column2", "column3" }; } [Benchmark(Baseline = true)] // 将该方法设为基准线,方便对比其他方法的相对性能 public bool TestClass1() { var class1 = new Class1(); return class1.Run(ref _columns); } [Benchmark] public bool TestClass2() { var class2 = new Class2(); return class2.Run(ref _columns); } [Benchmark] public bool TestClass3() { var class3 = new Class3(); return class3.Run(ref _columns); } }
运行时只需调用:
BenchmarkRunner.Run<AllBenchmarks>();
方式2:一次性运行多个测试类
如果要保留原有的三个类结构,可以通过传入类型数组一次性运行所有测试:
BenchmarkRunner.Run(new[] { typeof(Class1), typeof(Class2), typeof(Class3) });
两种方式都会生成包含所有方法性能数据的对比报告,其中会展示每个方法的执行时间、分配内存等指标,以及相对基准线的性能差异百分比,比单独测试更便于对比。
内容的提问来源于stack exchange,提问作者Jonathan Wood
相关产品推荐
相关产品推荐

