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; } }