一、基准测试
基准测试(benchmarking)是一种测量和评估软件性能指标的活动。你可以在某个时候通过基准测试建立一个已知的性能水平(称为基准线),当系统的软硬件环境发生变化之后再进行一次基准测试以确定那些变化对性能的影响。这是基准测试最常见的用途。其他用途包括测定某种负载水平下的性能极限、管理系统或环境的变化、发现可能导致性能问题的条件,等等。
基准测试和压力测试是性能测试两大组成部分。
二、NuGet安装BenchmarkDotNet
我们可以通过NuGet命令来安装BenchmarkDotNet。
Install-Package BenchmarkDotNet
也可以通过图形化NuGet界面安装:
三、编写基准测试代码
创建一个BenchmarkDotNet类,并在需要测试的方法中标记Benchmark特性。以我自己的一个自定义程序集中主要方法的性能测试为例:
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
using Humbunklung.SpreadSheetCalculator.Core;
using Humbunklung.SpreadSheetCalculator.Data;
using Humbunklung.SpreadSheetCalculator.Position;
BenchmarkRunner.Run<SpreadSheetCalculatorBenchmark>();
[MemoryDiagnoser, RankColumn]
public class SpreadSheetCalculatorBenchmark
{
private static readonly string WorkbookPath = $@"{Environment.CurrentDirectory}{Path.DirectorySeparatorChar}workbook.xlsx";
[Benchmark]
public void CalculateAll()
{
using (var cal = new WorkbookCalculator(WorkbookPath))
{
var inputData = new Dictionary<CellPositionInfo, CellValueData>();
var outputData = new Dictionary<CellPositionInfo, CellValueType>();
inputData.Add(new CellPositionInfo { SheetName = "管道计算 (混凝土管道简化指标)", ColIndex = 1, RowIndex = 2 }, new CellValueData { ValueType = CellValueType.NumericCellValue, Value = 250 });
outputData.Add(new CellPositionInfo { SheetName = "管道计算 (混凝土管道简化指标)", ColIndex = 25, RowIndex = 2 }, CellValueType.NumericCellValue);
outputData.Add(new CellAddressInfo { SheetName = "管道计算 (混凝土管道简化指标)", CellAddress = "AJ3" }.ToCellPositionInfo(), CellValueType.NumericCellValue);
cal.Compute(inputData, outputData);
}
}
[Benchmark]
public void CalculateSpecified()
{
using (var cal = new WorkbookCalculator(WorkbookPath))
{
var inputData = new Dictionary<CellPositionInfo, CellValueData>();
var outputData = new Dictionary<CellPositionInfo, CellValueType>();
inputData.Add(new CellPositionInfo { SheetName = "管道计算 (混凝土管道简化指标)", ColIndex = 1, RowIndex = 2 }, new CellValueData { ValueType = CellValueType.NumericCellValue, Value = 250 });
outputData.Add(new CellPositionInfo { SheetName = "管道计算 (混凝土管道简化指标)", ColIndex = 25, RowIndex = 2 }, CellValueType.NumericCellValue);
outputData.Add(new CellAddressInfo { SheetName = "管道计算 (混凝土管道简化指标)", CellAddress = "AJ3" }.ToCellPositionInfo(), CellValueType.NumericCellValue);
cal.Evaluate(inputData, outputData);
}
}
[Benchmark]
public void CalculateFormulas()
{
using (var cal = new WorkbookCalculator(WorkbookPath))
{
var inputData = new Dictionary<CellPositionInfo, CellValueData>();
var outputData = new Dictionary<CellPositionInfo, CellValueType>();
inputData.Add(new CellPositionInfo { SheetName = "管道计算 (混凝土管道简化指标)", ColIndex = 1, RowIndex = 2 }, new CellValueData { ValueType = CellValueType.NumericCellValue, Value = 250 });
outputData.Add(new CellPositionInfo { SheetName = "管道计算 (混凝土管道简化指标)", ColIndex = 25, RowIndex = 2 }, CellValueType.NumericCellValue);
outputData.Add(new CellAddressInfo { SheetName = "管道计算 (混凝土管道简化指标)", CellAddress = "AJ3" }.ToCellPositionInfo(), CellValueType.NumericCellValue);
cal.EvaluateFormulas(inputData, outputData);
}
}
}
四、运行Benchmark
作为一种性能测试,需要在Release模式下运行,在Debug模式下会报错。几个主要方法的测试结果如下: