Files
just 08036a31d5
.NET Test / .NET tests (push) Successful in 1m26s
the first optimization round
2026-09-14 13:58:04 +04:00

190 lines
5.9 KiB
C#

using BenchmarkDotNet.Attributes;
namespace Just.PreciseMath.Benchmarks;
/// <summary>Measures independent array operations, including loads, stores, and loop overhead.</summary>
[MemoryDiagnoser]
[CategoriesColumn]
public class ArithmeticThroughputBenchmarks
{
private DoubleDouble[] _left = [];
private DoubleDouble[] _right = [];
private double[] _scalarLeft = [];
private double[] _scalarRight = [];
private readonly DoubleDouble[] _results = new DoubleDouble[ArithmeticInputs.Count];
private readonly double[] _doubleResults = new double[ArithmeticInputs.Count];
[Params("BinaryExact", "DecimalResidual", "BothResidual", "Mixed", "SignsAndScales", "Cancellation")]
public string Scenario { get; set; } = "BothResidual";
[GlobalSetup]
public void Setup()
{
ArithmeticInputs inputs = ArithmeticInputs.Create(Scenario, false);
_left = inputs.Left;
_right = inputs.Right;
_scalarLeft = Array.ConvertAll(_left, value => value.High);
_scalarRight = Array.ConvertAll(_right, value => value.High);
}
[Benchmark(OperationsPerInvoke = ArithmeticInputs.Count), BenchmarkCategory("Addition")]
public DoubleDouble[] DDAdd()
{
for (int i = 0; i < ArithmeticInputs.Count; i++)
{
_results[i] = _left[i] + _right[i];
}
return _results;
}
[Benchmark(OperationsPerInvoke = ArithmeticInputs.Count), BenchmarkCategory("Addition")]
public DoubleDouble[] DDScalarAdd()
{
for (int i = 0; i < ArithmeticInputs.Count; i++)
{
_results[i] = _left[i] + _scalarRight[i];
}
return _results;
}
[Benchmark(OperationsPerInvoke = ArithmeticInputs.Count), BenchmarkCategory("Addition")]
public DoubleDouble[] ScalarDDAdd()
{
for (int i = 0; i < ArithmeticInputs.Count; i++)
{
_results[i] = _scalarLeft[i] + _right[i];
}
return _results;
}
[Benchmark(OperationsPerInvoke = ArithmeticInputs.Count), BenchmarkCategory("Addition")]
public double[] DoubleAdd()
{
for (int i = 0; i < ArithmeticInputs.Count; i++)
{
_doubleResults[i] = _scalarLeft[i] + _scalarRight[i];
}
return _doubleResults;
}
[Benchmark(OperationsPerInvoke = ArithmeticInputs.Count), BenchmarkCategory("Subtraction")]
public DoubleDouble[] DDSubtract()
{
for (int i = 0; i < ArithmeticInputs.Count; i++)
{
_results[i] = _left[i] - _right[i];
}
return _results;
}
[Benchmark(OperationsPerInvoke = ArithmeticInputs.Count), BenchmarkCategory("Subtraction")]
public DoubleDouble[] DDScalarSubtract()
{
for (int i = 0; i < ArithmeticInputs.Count; i++)
{
_results[i] = _left[i] - _scalarRight[i];
}
return _results;
}
[Benchmark(OperationsPerInvoke = ArithmeticInputs.Count), BenchmarkCategory("Subtraction")]
public DoubleDouble[] ScalarDDSubtract()
{
for (int i = 0; i < ArithmeticInputs.Count; i++)
{
_results[i] = _scalarLeft[i] - _right[i];
}
return _results;
}
[Benchmark(OperationsPerInvoke = ArithmeticInputs.Count), BenchmarkCategory("Subtraction")]
public double[] DoubleSubtract()
{
for (int i = 0; i < ArithmeticInputs.Count; i++)
{
_doubleResults[i] = _scalarLeft[i] - _scalarRight[i];
}
return _doubleResults;
}
[Benchmark(OperationsPerInvoke = ArithmeticInputs.Count), BenchmarkCategory("Multiplication")]
public DoubleDouble[] DDMultiply()
{
for (int i = 0; i < ArithmeticInputs.Count; i++)
{
_results[i] = _left[i] * _right[i];
}
return _results;
}
[Benchmark(OperationsPerInvoke = ArithmeticInputs.Count), BenchmarkCategory("Multiplication")]
public DoubleDouble[] DDScalarMultiply()
{
for (int i = 0; i < ArithmeticInputs.Count; i++)
{
_results[i] = _left[i] * _scalarRight[i];
}
return _results;
}
[Benchmark(OperationsPerInvoke = ArithmeticInputs.Count), BenchmarkCategory("Multiplication")]
public DoubleDouble[] ScalarDDMultiply()
{
for (int i = 0; i < ArithmeticInputs.Count; i++)
{
_results[i] = _scalarLeft[i] * _right[i];
}
return _results;
}
[Benchmark(OperationsPerInvoke = ArithmeticInputs.Count), BenchmarkCategory("Multiplication")]
public double[] DoubleMultiply()
{
for (int i = 0; i < ArithmeticInputs.Count; i++)
{
_doubleResults[i] = _scalarLeft[i] * _scalarRight[i];
}
return _doubleResults;
}
[Benchmark(OperationsPerInvoke = ArithmeticInputs.Count), BenchmarkCategory("Division")]
public DoubleDouble[] DDDivide()
{
for (int i = 0; i < ArithmeticInputs.Count; i++)
{
_results[i] = _left[i] / _right[i];
}
return _results;
}
[Benchmark(OperationsPerInvoke = ArithmeticInputs.Count), BenchmarkCategory("Division")]
public DoubleDouble[] DDScalarDivide()
{
for (int i = 0; i < ArithmeticInputs.Count; i++)
{
_results[i] = _left[i] / _scalarRight[i];
}
return _results;
}
[Benchmark(OperationsPerInvoke = ArithmeticInputs.Count), BenchmarkCategory("Division")]
public DoubleDouble[] ScalarDDDivide()
{
for (int i = 0; i < ArithmeticInputs.Count; i++)
{
_results[i] = _scalarLeft[i] / _right[i];
}
return _results;
}
[Benchmark(OperationsPerInvoke = ArithmeticInputs.Count), BenchmarkCategory("Division")]
public double[] DoubleDivide()
{
for (int i = 0; i < ArithmeticInputs.Count; i++)
{
_doubleResults[i] = _scalarLeft[i] / _scalarRight[i];
}
return _doubleResults;
}
}