using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;
namespace Just.PreciseMath.Benchmarks;
/// Compares same-type scalar arithmetic on ordinary finite operands.
[MemoryDiagnoser]
[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)]
[CategoriesColumn]
public class ArithmeticBenchmarks
{
private double _doubleLeft;
private double _doubleRight;
private decimal _decimalLeft;
private decimal _decimalRight;
private DoubleDouble _doubleDoubleLeft;
private DoubleDouble _doubleDoubleRight;
/// One binary-exact input and one decimal input with a binary residual.
[Params(1.25, 1.1)]
public double Left { get; set; }
[GlobalSetup]
public void Setup()
{
// Conversion and construction are deliberately outside the timed methods.
// Decimal and DoubleDouble represent the same decimal input; double rounds it.
_doubleLeft = Left;
_doubleRight = 0.75;
_decimalLeft = (decimal)Left;
_decimalRight = 0.75m;
_doubleDoubleLeft = (DoubleDouble)_decimalLeft;
_doubleDoubleRight = (DoubleDouble)_decimalRight;
}
[Benchmark(Baseline = true), BenchmarkCategory("Addition")]
public double DoubleAdd()
{
return _doubleLeft + _doubleRight;
}
[Benchmark, BenchmarkCategory("Addition")]
public decimal DecimalAdd()
{
return _decimalLeft + _decimalRight;
}
[Benchmark, BenchmarkCategory("Addition")]
public DoubleDouble DoubleDoubleAdd()
{
return _doubleDoubleLeft + _doubleDoubleRight;
}
[Benchmark(Baseline = true), BenchmarkCategory("Subtraction")]
public double DoubleSubtract()
{
return _doubleLeft - _doubleRight;
}
[Benchmark, BenchmarkCategory("Subtraction")]
public decimal DecimalSubtract()
{
return _decimalLeft - _decimalRight;
}
[Benchmark, BenchmarkCategory("Subtraction")]
public DoubleDouble DoubleDoubleSubtract()
{
return _doubleDoubleLeft - _doubleDoubleRight;
}
[Benchmark(Baseline = true), BenchmarkCategory("Multiplication")]
public double DoubleMultiply()
{
return _doubleLeft * _doubleRight;
}
[Benchmark, BenchmarkCategory("Multiplication")]
public decimal DecimalMultiply()
{
return _decimalLeft * _decimalRight;
}
[Benchmark, BenchmarkCategory("Multiplication")]
public DoubleDouble DoubleDoubleMultiply()
{
return _doubleDoubleLeft * _doubleDoubleRight;
}
[Benchmark(Baseline = true), BenchmarkCategory("Division")]
public double DoubleDivide()
{
return _doubleLeft / _doubleRight;
}
[Benchmark, BenchmarkCategory("Division")]
public decimal DecimalDivide()
{
return _decimalLeft / _decimalRight;
}
[Benchmark, BenchmarkCategory("Division")]
public DoubleDouble DoubleDoubleDivide()
{
return _doubleDoubleLeft / _doubleDoubleRight;
}
}