the first optimization round
.NET Test / .NET tests (push) Successful in 1m26s

This commit is contained in:
2026-09-14 13:58:04 +04:00
parent cb2524980d
commit 08036a31d5
12 changed files with 1316 additions and 49 deletions
@@ -0,0 +1,189 @@
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;
}
}