Skip to content

Instantly share code, notes, and snippets.

@guitarrapc
Last active October 22, 2025 09:54
Show Gist options
  • Save guitarrapc/1ad610d5757231146385e7091c0afa6e to your computer and use it in GitHub Desktop.
Save guitarrapc/1ad610d5757231146385e7091c0afa6e to your computer and use it in GitHub Desktop.
Math.Pow Benchmark

// * Summary *

BenchmarkDotNet v0.15.4, Windows 11 (10.0.26100.6899/24H2/2024Update/HudsonValley) AMD Ryzen 7 5800H with Radeon Graphics 3.20GHz, 1 CPU, 16 logical and 8 physical cores .NET SDK 10.0.100-rc.2.25502.107 [Host] : .NET 9.0.9 (9.0.9, 9.0.925.41916), X64 RyuJIT x86-64-v3

IterationCount=3 LaunchCount=1 WarmupCount=3

Method Job Runtime PointCount Mean Error StdDev Ratio RatioSD Allocated Alloc Ratio
Double_Pow ShortRun-.NET 10.0 .NET 10.0 10000 2.644 μs 1.684 μs 0.0923 μs 1.00 0.04 - NA
Double_PowROS ShortRun-.NET 10.0 .NET 10.0 10000 352.116 μs 33.971 μs 1.8620 μs 133.30 4.01 3 B NA
Double_DirectROS ShortRun-.NET 10.0 .NET 10.0 10000 9.262 μs 18.449 μs 1.0112 μs 3.51 0.35 - NA
Int_Pow ShortRun-.NET 10.0 .NET 10.0 10000 473.937 μs 329.338 μs 18.0521 μs 179.42 7.97 3 B NA
Int_PowROS ShortRun-.NET 10.0 .NET 10.0 10000 479.320 μs 151.496 μs 8.3040 μs 181.46 6.04 6 B NA
Int_DirectROS ShortRun-.NET 10.0 .NET 10.0 10000 23.130 μs 7.121 μs 0.3903 μs 8.76 0.29 - NA
Double_Pow ShortRun-.NET 9.0 .NET 9.0 10000 4.244 μs 3.896 μs 0.2136 μs 1.00 0.06 - NA
Double_PowROS ShortRun-.NET 9.0 .NET 9.0 10000 449.331 μs 86.596 μs 4.7466 μs 106.06 4.78 3 B NA
Double_DirectROS ShortRun-.NET 9.0 .NET 9.0 10000 10.988 μs 3.904 μs 0.2140 μs 2.59 0.12 - NA
Int_Pow ShortRun-.NET 9.0 .NET 9.0 10000 462.085 μs 142.679 μs 7.8207 μs 109.07 5.07 3 B NA
Int_PowROS ShortRun-.NET 9.0 .NET 9.0 10000 484.069 μs 139.801 μs 7.6629 μs 114.26 5.28 6 B NA
Int_DirectROS ShortRun-.NET 9.0 .NET 9.0 10000 22.972 μs 2.096 μs 0.1149 μs 5.42 0.24 - NA
Double_Pow ShortRun-.NET 10.0 .NET 10.0 100000 40.356 μs 22.206 μs 1.2172 μs 1.00 0.04 - NA
Double_PowROS ShortRun-.NET 10.0 .NET 10.0 100000 4,643.936 μs 3,333.460 μs 182.7182 μs 115.14 4.93 47 B NA
Double_DirectROS ShortRun-.NET 10.0 .NET 10.0 100000 109.447 μs 57.650 μs 3.1600 μs 2.71 0.10 1 B NA
Int_Pow ShortRun-.NET 10.0 .NET 10.0 100000 4,607.316 μs 1,625.147 μs 89.0798 μs 114.24 3.52 50 B NA
Int_PowROS ShortRun-.NET 10.0 .NET 10.0 100000 4,907.716 μs 1,934.698 μs 106.0473 μs 121.68 3.88 47 B NA
Int_DirectROS ShortRun-.NET 10.0 .NET 10.0 100000 238.909 μs 88.281 μs 4.8390 μs 5.92 0.19 - NA
Double_Pow ShortRun-.NET 9.0 .NET 9.0 100000 43.554 μs 88.422 μs 4.8467 μs 1.01 0.13 - NA
Double_PowROS ShortRun-.NET 9.0 .NET 9.0 100000 4,722.780 μs 716.105 μs 39.2521 μs 109.28 9.95 50 B NA
Double_DirectROS ShortRun-.NET 9.0 .NET 9.0 100000 108.672 μs 39.930 μs 2.1887 μs 2.51 0.23 1 B NA
Int_Pow ShortRun-.NET 9.0 .NET 9.0 100000 4,807.317 μs 2,516.418 μs 137.9334 μs 111.24 10.47 47 B NA
Int_PowROS ShortRun-.NET 9.0 .NET 9.0 100000 4,911.304 μs 2,381.235 μs 130.5235 μs 113.65 10.64 50 B NA
Int_DirectROS ShortRun-.NET 9.0 .NET 9.0 100000 234.013 μs 38.061 μs 2.0862 μs 5.42 0.49 2 B NA
Double_Pow ShortRun-.NET 10.0 .NET 10.0 1000000 444.098 μs 612.718 μs 33.5851 μs 1.00 0.10 3 B 1.00
Double_PowROS ShortRun-.NET 10.0 .NET 10.0 1000000 49,387.973 μs 64,354.313 μs 3,527.4771 μs 111.65 10.31 576 B 192.00
Double_DirectROS ShortRun-.NET 10.0 .NET 10.0 1000000 1,497.523 μs 2,395.581 μs 131.3099 μs 3.39 0.35 12 B 4.00
Int_Pow ShortRun-.NET 10.0 .NET 10.0 1000000 46,843.064 μs 3,066.241 μs 168.0710 μs 105.90 7.26 576 B 192.00
Int_PowROS ShortRun-.NET 10.0 .NET 10.0 1000000 50,534.864 μs 37,770.834 μs 2,070.3469 μs 114.25 8.82 576 B 192.00
Int_DirectROS ShortRun-.NET 10.0 .NET 10.0 1000000 2,476.020 μs 612.857 μs 33.5928 μs 5.60 0.39 25 B 8.33
Double_Pow ShortRun-.NET 9.0 .NET 9.0 1000000 428.667 μs 530.310 μs 29.0681 μs 1.00 0.08 3 B 1.00
Double_PowROS ShortRun-.NET 9.0 .NET 9.0 1000000 44,247.455 μs 17,601.923 μs 964.8208 μs 103.55 6.57 550 B 183.33
Double_DirectROS ShortRun-.NET 9.0 .NET 9.0 1000000 1,337.708 μs 1,511.331 μs 82.8411 μs 3.13 0.25 12 B 4.00
Int_Pow ShortRun-.NET 9.0 .NET 9.0 1000000 47,207.203 μs 42,337.364 μs 2,320.6538 μs 110.47 8.18 550 B 183.33
Int_PowROS ShortRun-.NET 9.0 .NET 9.0 1000000 50,443.848 μs 34,993.836 μs 1,918.1303 μs 118.05 8.14 576 B 192.00
Int_DirectROS ShortRun-.NET 9.0 .NET 9.0 1000000 2,361.276 μs 97.503 μs 5.3444 μs 5.53 0.33 25 B 8.33

// * Legends * PointCount : Value of the 'PointCount' parameter Mean : Arithmetic mean of all measurements Error : Half of 99.9% confidence interval StdDev : Standard deviation of all measurements Ratio : Mean of the ratio distribution ([Current]/[Baseline]) RatioSD : Standard deviation of the ratio distribution ([Current]/[Baseline]) Allocated : Allocated memory per single operation (managed only, inclusive, 1KB = 1024B) Alloc Ratio : Allocated memory ratio distribution ([Current]/[Baseline]) 1 μs : 1 Microsecond (0.000001 sec)

BenchmarkRunner.Run<DistanceBench>();
[ShortRunJob(RuntimeMoniker.Net90)]
[ShortRunJob(RuntimeMoniker.Net10_0)]
[MemoryDiagnoser]
public class DistanceBench
{
[Params(10_000, 100_000, 1_000_000)]
public int PointCount { get; set; }
private Point[] _points = default!;
private PointInt[] _pointsInt = default!;
[GlobalSetup]
public void Setup()
{
var rnd = new Random(1234);
_points = new Point[PointCount];
_pointsInt = new PointInt[PointCount];
for (int i = 0; i < PointCount; i++)
{
_points[i] = new Point(rnd.NextDouble() * 1000, rnd.NextDouble() * 1000);
}
for (int i = 0; i < PointCount; i++)
{
_pointsInt[i] = new PointInt(rnd.Next(), rnd.Next());
}
}
[Benchmark(Baseline = true)]
public void Double_Pow() => Pow(_points);
[Benchmark]
public void Double_PowROS() => Pow_ROS(_points.AsSpan());
[Benchmark]
public void Double_DirectROS() => Direct_ROS(_points.AsSpan());
[Benchmark]
public void Int_Pow() => Pow(_pointsInt);
[Benchmark]
public void Int_PowROS() => Pow_ROS(_pointsInt.AsSpan());
[Benchmark]
public void Int_DirectROS() => Direct_ROS(_pointsInt.AsSpan());
private static double Pow(Point[] inputs)
{
double sqrt = 0;
for (var i = 0; i < inputs.Length - 1; i++)
{
var dx = inputs[i + 1].X - inputs[i].X;
var dy = inputs[i + 1].Y - inputs[i].Y;
_ = Math.Pow(dx, 2) + Math.Pow(dy, 2);
}
return sqrt;
}
private static double Pow_ROS(ReadOnlySpan<Point> span)
{
double sqrt = 0;
for (var i = 0; i < span.Length - 1; i++)
{
var dx = span[i + 1].X - span[i].X;
var dy = span[i + 1].Y - span[i].Y;
sqrt += Math.Pow(dx, 2) + Math.Pow(dy, 2);
}
return sqrt;
}
private static double Direct_ROS(ReadOnlySpan<Point> span)
{
double sqrt = 0;
for (var i = 0; i < span.Length - 1; i++)
{
var dx = span[i + 1].X - span[i].X;
var dy = span[i + 1].Y - span[i].Y;
sqrt += dx * dx + dy * dy;
}
return sqrt;
}
private static double Pow(PointInt[] inputs)
{
double sqrt = 0;
for (var i = 0; i < inputs.Length - 1; i++)
{
var dx = inputs[i + 1].X - inputs[i].X;
var dy = inputs[i + 1].Y - inputs[i].Y;
sqrt += Math.Pow(dx, 2) + Math.Pow(dy, 2);
}
return sqrt;
}
private static double Pow_ROS(ReadOnlySpan<PointInt> span)
{
double sqrt = 0;
for (var i = 0; i < span.Length - 1; i++)
{
var dx = span[i + 1].X - span[i].X;
var dy = span[i + 1].Y - span[i].Y;
sqrt += Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2));
}
return sqrt;
}
private static double Direct_ROS(ReadOnlySpan<PointInt> span)
{
double sqrt = 0;
for (var i = 0; i < span.Length - 1; i++)
{
var dx = span[i + 1].X - span[i].X;
var dy = span[i + 1].Y - span[i].Y;
sqrt += Math.Sqrt(dx * dx + dy * dy);
}
return sqrt;
}
}
[StructLayout(LayoutKind.Sequential)]
public readonly record struct Point(double X, double Y);
[StructLayout(LayoutKind.Sequential)]
public readonly record struct PointInt(int X, int Y);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment