From 4b4884f7bf814fe4691d4d8c425b97819d654b44 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 16 Sep 2026 10:46:35 +0000 Subject: [PATCH 1/3] Chart the quantity wrapper's cost per release [patch] AbstractionCostBenchmarks already measured what a quantity costs over the bare storage type it wraps. This draws that per release, as a third chart section, so the answer is watched rather than taken once. The same section, from the same shared tool, goes into ktsu.PreciseNumber and ktsu.SignificantNumber, where the pair being divided is that library's type against a bare double. Here the divisor is the storage type the quantity holds, which is why this caption reads differently: a quantity holds one value and adds no work of its own, so this section belongs at 1 and a departure from it is the finding. There the ratio is the price of arbitrary precision, well above 1 and rightly so, and what matters is that it stays put. Four panels rather than two, because the storage type is this library's axis: Add over double, then Multiply over double, decimal and PreciseNumber. Multiply is the one to watch, being the generated relationship that lands on another dimension. The section derives its ratio from two benchmarks already stored rather than recording a new field, so there is no schema change, no history to rewrite, and an entry gathered before the pair existed simply draws as not measured. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_017jrnV7N94UGL8fDRRE8Xt8 --- .github/workflows/benchmark-history.yml | 1 + scripts/benchmark-history.cs | 112 ++++++++++++++++++++---- 2 files changed, 98 insertions(+), 15 deletions(-) diff --git a/.github/workflows/benchmark-history.yml b/.github/workflows/benchmark-history.yml index 57841c2..b835dae 100644 --- a/.github/workflows/benchmark-history.yml +++ b/.github/workflows/benchmark-history.yml @@ -50,6 +50,7 @@ env: *OperatorBenchmarks*LengthTimesLength *VectorBenchmarks*.Length *ComparisonBenchmarks*CompareToInterface + *AbstractionCostBenchmarks* # Short runs: three iterations is enough for a trend line, and a release should not tie up a # runner for half an hour. BENCHMARK_JOB: short diff --git a/scripts/benchmark-history.cs b/scripts/benchmark-history.cs index c1161f0..0e09f05 100644 --- a/scripts/benchmark-history.cs +++ b/scripts/benchmark-history.cs @@ -69,12 +69,41 @@ private static readonly (string Key, string? Parameters, string Label)[] Headlin /// private static readonly Dictionary Themes = new(StringComparer.Ordinal) { - ["light"] = new("#fcfcfb", "#0b0b0b", "#52514e", "#e4e3df", "#2a78d6", "#eb6834"), - ["dark"] = new("#1a1a19", "#ffffff", "#c3c2b7", "#333330", "#3987e5", "#d95926"), + ["light"] = new("#fcfcfb", "#0b0b0b", "#52514e", "#e4e3df", "#2a78d6", "#eb6834", "#2e8b57"), + ["dark"] = new("#1a1a19", "#ffffff", "#c3c2b7", "#333330", "#3987e5", "#d95926", "#3faa71"), }; private sealed record Theme( - string Surface, string Ink, string Muted, string Grid, string Alloc, string Time); + string Surface, string Ink, string Muted, string Grid, string Alloc, string Time, string Cost); + + /// Which of the three things a section draws. + private enum Measure + { + /// Bytes allocated per operation, as stored. + Allocation, + + /// Time, divided by the reference workload from the same job. + Time, + + /// Time, divided by the paired bare-double benchmark from the same entry. + Cost, + } + + /// + /// The paired benchmarks the cost section draws, as (measured, baseline, label). + /// + /// + /// Both halves are stored like any other benchmark; the ratio is computed here rather than + /// recorded, so an entry gathered before this section existed still draws once its run + /// includes the pair, and no history has to be rewritten to change what the section shows. + /// + private static readonly (string Key, string Baseline, string Label)[] CostHeadline = + [ + ("AbstractionCostBenchmarks.QuantityAdd", "AbstractionCostBenchmarks.BareAdd", "Add (double)"), + ("AbstractionCostBenchmarks.QuantityMultiply", "AbstractionCostBenchmarks.BareMultiply", "Multiply (double)"), + ("AbstractionCostBenchmarks.QuantityMultiply", "AbstractionCostBenchmarks.BareMultiply", "Multiply (decimal)"), + ("AbstractionCostBenchmarks.QuantityMultiply", "AbstractionCostBenchmarks.BareMultiply", "Multiply (precise)"), + ]; internal static int Run(string[] args) { @@ -422,16 +451,17 @@ private static string Draw(JsonArray entries, Theme theme) string[] labels = [.. entries.Select(entry => entry!["version"]?.GetValue() ?? "?")]; int width = Left + (Columns * CellWidth) + 24; int rows = (Headline.Length + Columns - 1) / Columns; - int height = 72 + (((34 + (rows * CellHeight)) * 2) + 54); + int costRows = (CostHeadline.Length + Columns - 1) / Columns; + int height = 72 + ((34 + (rows * CellHeight)) * 2) + 34 + (costRows * CellHeight) + 54; StringBuilder svg = new(); Preamble(svg, theme, width, height, entries); int y = 72; - foreach (bool isTime in (bool[])[false, true]) + foreach (Measure measure in (Measure[])[Measure.Allocation, Measure.Time, Measure.Cost]) { - Section(svg, theme, entries, labels.Length, y, isTime); - y += 34 + (rows * CellHeight); + Section(svg, theme, entries, labels.Length, y, measure); + y += 34 + ((measure == Measure.Cost ? costRows : rows) * CellHeight); } Footer(svg, entries, labels, y - 4); @@ -461,20 +491,53 @@ private static void Preamble(StringBuilder svg, Theme theme, int width, int heig svg.AppendLine(CultureInfo.InvariantCulture, $"""{entries.Count} releases · newest {Escape(latest["version"]?.GetValue() ?? "?")}{suffix}"""); } - private static void Section(StringBuilder svg, Theme theme, JsonArray entries, int points, int y, bool isTime) + private static void Section(StringBuilder svg, Theme theme, JsonArray entries, int points, int y, Measure measure) { - string colour = isTime ? theme.Time : theme.Alloc; - string title = isTime - ? "Time, as a multiple of a fixed reference workload" - : "Allocated bytes per operation"; - string note = isTime - ? "Divided by a reference loop measured in the same job, which cancels most of the difference between CI runners. Lower is faster." - : "Deterministic: the same code allocates the same bytes on any machine."; + string colour = measure switch + { + Measure.Time => theme.Time, + Measure.Cost => theme.Cost, + _ => theme.Alloc, + }; + string title = measure switch + { + Measure.Time => "Time, as a multiple of a fixed reference workload", + Measure.Cost => "Cost of the quantity wrapper over the bare storage type", + _ => "Allocated bytes per operation", + }; + string note = measure switch + { + Measure.Time => "Divided by a reference loop measured in the same job, which cancels most of the difference between CI runners. Lower is faster.", + Measure.Cost => "Divided by the identical loop on the bare storage type, measured beside it. A quantity holds one value and adds no work of its own, so this belongs at 1.", + _ => "Deterministic: the same code allocates the same bytes on any machine.", + }; svg.AppendLine(CultureInfo.InvariantCulture, $""""""); svg.AppendLine(CultureInfo.InvariantCulture, $"""{Escape(title)}"""); svg.AppendLine(CultureInfo.InvariantCulture, $"""{Escape(note)}"""); + if (measure == Measure.Cost) + { + for (int position = 0; position < CostHeadline.Length; position++) + { + (string key, string baseline, string label) = CostHeadline[position]; + double?[] values = [.. entries.Select(entry => Cost(entry!, key, baseline))]; + Panel( + svg, + Left + (position % Columns * CellWidth), + y + 26 + (position / Columns * CellHeight), + label, + points, + values, + true, + colour, + theme); + } + + return; + } + + bool isTime = measure == Measure.Time; for (int position = 0; position < Headline.Length; position++) { (string key, string? parameters, string label) = Headline[position]; @@ -492,6 +555,25 @@ private static void Section(StringBuilder svg, Theme theme, JsonArray entries, i } } + /// + /// One benchmark's mean divided by the mean of the bare-double benchmark beside it. + /// + /// + /// Both were measured in the same job on the same machine, so unlike the time section this + /// needs no reference workload to be comparable across runs: the denominator is the reference. + /// + private static double? Cost(JsonNode entry, string key, string baseline) + { + double? measured = Mean(entry, key); + double? divisor = Mean(entry, baseline); + return measured is not null && divisor is > 0 ? measured / divisor : null; + } + + private static double? Mean(JsonNode entry, string key) => + entry["benchmarks"]?[key] is JsonObject cases && cases.Count > 0 + ? cases.First().Value?["meanNs"]?.GetValue() + : null; + private static double? Value(JsonNode entry, string key, string? parameters, bool isTime) { if (entry["benchmarks"]?[key] is not JsonObject cases || cases.Count == 0) From 68046e2983bf82ba58e8f7e337c10dde2f962d1a Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 16 Sep 2026 11:44:10 +0000 Subject: [PATCH 2/3] Compile the abstraction-cost benchmark against pre-4.0 quantities [patch] The backfill now runs this class, and before 4.0 a quantity was a class, where an unassigned field is a null reference the compiler rejects. Same default! the other benchmark classes already carry; this one was added after them and was not in the backfill filter until now, so 3.3.1 was the first version to ask it to compile. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_017jrnV7N94UGL8fDRRE8Xt8 --- .../AbstractionCostBenchmarks.cs | 10 +- docs/benchmarks/history.json | 1096 ++--------------- 2 files changed, 127 insertions(+), 979 deletions(-) diff --git a/Semantics.Benchmarks/AbstractionCostBenchmarks.cs b/Semantics.Benchmarks/AbstractionCostBenchmarks.cs index d9e78a0..2f2af57 100644 --- a/Semantics.Benchmarks/AbstractionCostBenchmarks.cs +++ b/Semantics.Benchmarks/AbstractionCostBenchmarks.cs @@ -71,9 +71,13 @@ public class AbstractionCostBenchmarks private T step; private T other; - private Length seedLength; - private Length stepLength; - private Length otherLength; + // Assigned in GlobalSetup before anything is measured. Initialised here because a quantity + // was a class before 4.0, where an unassigned field is a null reference the compiler rejects; + // from 4.0 it is a record struct and this is simply its default. The backfill measures those + // releases too, so the file has to compile against both shapes. + private Length seedLength = default!; + private Length stepLength = default!; + private Length otherLength = default!; /// /// Prepares the operands, the bare ones and the wrapped ones holding the same values. diff --git a/docs/benchmarks/history.json b/docs/benchmarks/history.json index ec8ff53..22848e7 100644 --- a/docs/benchmarks/history.json +++ b/docs/benchmarks/history.json @@ -2,262 +2,227 @@ "schemaVersion": 1, "entries": [ { - "version": "3.3.1", - "commit": "fffa086", - "date": "2026-09-09", + "version": "4.0.0", + "commit": "496d895", + "date": "2026-09-10", "cpu": "Intel Xeon Processor 2.80GHz", "runtime": ".NET 10.0.12 (10.0.12, 10.0.1226.42308)", - "baselineNs": 454.7423, + "baselineNs": 453.7426, "runId": "local-seed", "benchmarks": { - "ComparisonBenchmarks\u003CDecimal\u003E.CompareToInterface": { + "AbstractionCostBenchmarks\u003CDecimal\u003E.BareAdd": { "": { - "meanNs": 8.6608, + "meanNs": 8.776, "allocatedBytes": 0 } }, - "ComparisonBenchmarks\u003CDouble\u003E.CompareToInterface": { + "AbstractionCostBenchmarks\u003CDecimal\u003E.BareMultiply": { "": { - "meanNs": 4.7739, + "meanNs": 82.3606, "allocatedBytes": 0 } }, - "ComparisonBenchmarks\u003CPreciseNumber\u003E.CompareToInterface": { + "AbstractionCostBenchmarks\u003CDecimal\u003E.QuantityAdd": { "": { - "meanNs": 11.5986, + "meanNs": 9.0495, "allocatedBytes": 0 } }, - "ComparisonBenchmarks\u003CSingle\u003E.CompareToInterface": { + "AbstractionCostBenchmarks\u003CDecimal\u003E.QuantityMultiply": { "": { - "meanNs": 5.6374, + "meanNs": 71.2207, "allocatedBytes": 0 } }, - "ConstructionBenchmarks\u003CDecimal\u003E.FromNauticalMile": { + "AbstractionCostBenchmarks\u003CDouble\u003E.BareAdd": { "": { - "meanNs": 43.4281, - "allocatedBytes": 64 + "meanNs": 0.99, + "allocatedBytes": 0 } }, - "ConstructionBenchmarks\u003CDouble\u003E.FromNauticalMile": { + "AbstractionCostBenchmarks\u003CDouble\u003E.BareMultiply": { "": { - "meanNs": 27.3741, - "allocatedBytes": 48 + "meanNs": 1.3734, + "allocatedBytes": 0 } }, - "ConstructionBenchmarks\u003CPreciseNumber\u003E.FromNauticalMile": { + "AbstractionCostBenchmarks\u003CDouble\u003E.QuantityAdd": { "": { - "meanNs": 519.2756, - "allocatedBytes": 120 + "meanNs": 1.0108, + "allocatedBytes": 0 } }, - "ConstructionBenchmarks\u003CSingle\u003E.FromNauticalMile": { + "AbstractionCostBenchmarks\u003CDouble\u003E.QuantityMultiply": { "": { - "meanNs": 28.3839, - "allocatedBytes": 48 + "meanNs": 1.2727, + "allocatedBytes": 0 } }, - "OperatorBenchmarks\u003CDecimal\u003E.LengthTimesLength": { + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.BareAdd": { "": { - "meanNs": 81.1407, + "meanNs": 97.9034, "allocatedBytes": 64 } }, - "OperatorBenchmarks\u003CDouble\u003E.LengthTimesLength": { - "": { - "meanNs": 35.0934, - "allocatedBytes": 48 - } - }, - "OperatorBenchmarks\u003CPreciseNumber\u003E.LengthTimesLength": { + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.BareMultiply": { "": { - "meanNs": 231.1584, - "allocatedBytes": 128 + "meanNs": 475.6775, + "allocatedBytes": 193 } }, - "OperatorBenchmarks\u003CSingle\u003E.LengthTimesLength": { + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.QuantityAdd": { "": { - "meanNs": 28.2983, - "allocatedBytes": 48 + "meanNs": 98.9475, + "allocatedBytes": 64 } }, - "UnitConversionBenchmarks\u003CDecimal\u003E.InNauticalMile": { + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.QuantityMultiply": { "": { - "meanNs": 71.2753, - "allocatedBytes": 0 + "meanNs": 493.3336, + "allocatedBytes": 193 } }, - "UnitConversionBenchmarks\u003CDouble\u003E.InNauticalMile": { + "AbstractionCostBenchmarks\u003CSingle\u003E.BareAdd": { "": { - "meanNs": 7.3582, + "meanNs": 0.993, "allocatedBytes": 0 } }, - "UnitConversionBenchmarks\u003CPreciseNumber\u003E.InNauticalMile": { - "": { - "meanNs": 989.1301, - "allocatedBytes": 232 - } - }, - "UnitConversionBenchmarks\u003CSingle\u003E.InNauticalMile": { + "AbstractionCostBenchmarks\u003CSingle\u003E.BareMultiply": { "": { - "meanNs": 7.1397, + "meanNs": 1.4008, "allocatedBytes": 0 } }, - "VectorBenchmarks\u003CDecimal\u003E.Length": { + "AbstractionCostBenchmarks\u003CSingle\u003E.QuantityAdd": { "": { - "meanNs": 163.2781, + "meanNs": 0.9897, "allocatedBytes": 0 } }, - "VectorBenchmarks\u003CDouble\u003E.Length": { + "AbstractionCostBenchmarks\u003CSingle\u003E.QuantityMultiply": { "": { - "meanNs": 1.002, + "meanNs": 1.2826, "allocatedBytes": 0 } }, - "VectorBenchmarks\u003CPreciseNumber\u003E.Length": { - "": { - "meanNs": 1827.4723, - "allocatedBytes": 312 - } - }, - "VectorBenchmarks\u003CSingle\u003E.Length": { - "": { - "meanNs": 0.8253, - "allocatedBytes": 0 - } - } - } - }, - { - "version": "4.0.0", - "commit": "496d895", - "date": "2026-09-10", - "cpu": "Intel Xeon Processor 2.80GHz", - "runtime": ".NET 10.0.12 (10.0.12, 10.0.1226.42308)", - "baselineNs": 454.7423, - "runId": "local-seed", - "benchmarks": { "ComparisonBenchmarks\u003CDecimal\u003E.CompareToInterface": { "": { - "meanNs": 20.3958, + "meanNs": 20.2386, "allocatedBytes": 32 } }, "ComparisonBenchmarks\u003CDouble\u003E.CompareToInterface": { "": { - "meanNs": 14.2212, + "meanNs": 14.5085, "allocatedBytes": 24 } }, "ComparisonBenchmarks\u003CPreciseNumber\u003E.CompareToInterface": { "": { - "meanNs": 34.4273, + "meanNs": 32.8639, "allocatedBytes": 40 } }, "ComparisonBenchmarks\u003CSingle\u003E.CompareToInterface": { "": { - "meanNs": 13.928, + "meanNs": 14.4357, "allocatedBytes": 24 } }, "ConstructionBenchmarks\u003CDecimal\u003E.FromNauticalMile": { "": { - "meanNs": 9.117, + "meanNs": 9.0862, "allocatedBytes": 0 } }, "ConstructionBenchmarks\u003CDouble\u003E.FromNauticalMile": { "": { - "meanNs": 3.364, + "meanNs": 3.3251, "allocatedBytes": 0 } }, "ConstructionBenchmarks\u003CPreciseNumber\u003E.FromNauticalMile": { "": { - "meanNs": 443.2553, + "meanNs": 446.0617, "allocatedBytes": 40 } }, "ConstructionBenchmarks\u003CSingle\u003E.FromNauticalMile": { "": { - "meanNs": 0.9414, + "meanNs": 0.9778, "allocatedBytes": 0 } }, "OperatorBenchmarks\u003CDecimal\u003E.LengthTimesLength": { "": { - "meanNs": 49.7154, + "meanNs": 48.6939, "allocatedBytes": 0 } }, "OperatorBenchmarks\u003CDouble\u003E.LengthTimesLength": { "": { - "meanNs": 0.0007, + "meanNs": 0.0016, "allocatedBytes": 0 } }, "OperatorBenchmarks\u003CPreciseNumber\u003E.LengthTimesLength": { "": { - "meanNs": 169.1601, + "meanNs": 169.1685, "allocatedBytes": 48 } }, "OperatorBenchmarks\u003CSingle\u003E.LengthTimesLength": { "": { - "meanNs": 0, + "meanNs": 0.0029, "allocatedBytes": 0 } }, "UnitConversionBenchmarks\u003CDecimal\u003E.InNauticalMile": { "": { - "meanNs": 70.1256, + "meanNs": 72.9641, "allocatedBytes": 0 } }, "UnitConversionBenchmarks\u003CDouble\u003E.InNauticalMile": { "": { - "meanNs": 8.4243, + "meanNs": 8.256, "allocatedBytes": 0 } }, "UnitConversionBenchmarks\u003CPreciseNumber\u003E.InNauticalMile": { "": { - "meanNs": 1045.9718, + "meanNs": 999.2178, "allocatedBytes": 232 } }, "UnitConversionBenchmarks\u003CSingle\u003E.InNauticalMile": { "": { - "meanNs": 7.1489, + "meanNs": 7.2326, "allocatedBytes": 0 } }, "VectorBenchmarks\u003CDecimal\u003E.Length": { "": { - "meanNs": 162.9532, + "meanNs": 160.8386, "allocatedBytes": 0 } }, "VectorBenchmarks\u003CDouble\u003E.Length": { "": { - "meanNs": 0.2999, + "meanNs": 0.3768, "allocatedBytes": 0 } }, "VectorBenchmarks\u003CPreciseNumber\u003E.Length": { "": { - "meanNs": 1791.7621, + "meanNs": 1798.0375, "allocatedBytes": 312 } }, "VectorBenchmarks\u003CSingle\u003E.Length": { "": { - "meanNs": 0.7062, + "meanNs": 0.6729, "allocatedBytes": 0 } } @@ -269,1043 +234,222 @@ "date": "2026-09-11", "cpu": "Intel Xeon Processor 2.80GHz", "runtime": ".NET 10.0.12 (10.0.12, 10.0.1226.42308)", - "baselineNs": 454.7423, + "baselineNs": 453.7426, "runId": "local-seed", "benchmarks": { - "ComparisonBenchmarks\u003CDecimal\u003E.CompareToInterface": { - "": { - "meanNs": 19.4354, - "allocatedBytes": 32 - } - }, - "ComparisonBenchmarks\u003CDouble\u003E.CompareToInterface": { - "": { - "meanNs": 14.2071, - "allocatedBytes": 24 - } - }, - "ComparisonBenchmarks\u003CPreciseNumber\u003E.CompareToInterface": { - "": { - "meanNs": 32.335, - "allocatedBytes": 40 - } - }, - "ComparisonBenchmarks\u003CSingle\u003E.CompareToInterface": { - "": { - "meanNs": 13.1068, - "allocatedBytes": 24 - } - }, - "ConstructionBenchmarks\u003CDecimal\u003E.FromNauticalMile": { - "": { - "meanNs": 9.0262, - "allocatedBytes": 0 - } - }, - "ConstructionBenchmarks\u003CDouble\u003E.FromNauticalMile": { - "": { - "meanNs": 3.3646, - "allocatedBytes": 0 - } - }, - "ConstructionBenchmarks\u003CPreciseNumber\u003E.FromNauticalMile": { - "": { - "meanNs": 458.7913, - "allocatedBytes": 40 - } - }, - "ConstructionBenchmarks\u003CSingle\u003E.FromNauticalMile": { - "": { - "meanNs": 1.1227, - "allocatedBytes": 0 - } - }, - "OperatorBenchmarks\u003CDecimal\u003E.LengthTimesLength": { - "": { - "meanNs": 49.6151, - "allocatedBytes": 0 - } - }, - "OperatorBenchmarks\u003CDouble\u003E.LengthTimesLength": { - "": { - "meanNs": 0.021, - "allocatedBytes": 0 - } - }, - "OperatorBenchmarks\u003CPreciseNumber\u003E.LengthTimesLength": { - "": { - "meanNs": 169.2628, - "allocatedBytes": 48 - } - }, - "OperatorBenchmarks\u003CSingle\u003E.LengthTimesLength": { - "": { - "meanNs": 0.0038, - "allocatedBytes": 0 - } - }, - "UnitConversionBenchmarks\u003CDecimal\u003E.InNauticalMile": { - "": { - "meanNs": 70.5234, - "allocatedBytes": 0 - } - }, - "UnitConversionBenchmarks\u003CDouble\u003E.InNauticalMile": { - "": { - "meanNs": 7.5685, - "allocatedBytes": 0 - } - }, - "UnitConversionBenchmarks\u003CPreciseNumber\u003E.InNauticalMile": { - "": { - "meanNs": 999.187, - "allocatedBytes": 232 - } - }, - "UnitConversionBenchmarks\u003CSingle\u003E.InNauticalMile": { + "AbstractionCostBenchmarks\u003CDecimal\u003E.BareAdd": { "": { - "meanNs": 7.9879, + "meanNs": 8.6348, "allocatedBytes": 0 } }, - "VectorBenchmarks\u003CDecimal\u003E.Length": { + "AbstractionCostBenchmarks\u003CDecimal\u003E.BareMultiply": { "": { - "meanNs": 165.9375, + "meanNs": 83.4205, "allocatedBytes": 0 } }, - "VectorBenchmarks\u003CDouble\u003E.Length": { + "AbstractionCostBenchmarks\u003CDecimal\u003E.QuantityAdd": { "": { - "meanNs": 0.3614, + "meanNs": 9.0842, "allocatedBytes": 0 } }, - "VectorBenchmarks\u003CPreciseNumber\u003E.Length": { - "": { - "meanNs": 1799.8658, - "allocatedBytes": 312 - } - }, - "VectorBenchmarks\u003CSingle\u003E.Length": { + "AbstractionCostBenchmarks\u003CDecimal\u003E.QuantityMultiply": { "": { - "meanNs": 0.7097, + "meanNs": 72.0806, "allocatedBytes": 0 } - } - } - }, - { - "version": "4.2.0", - "commit": "5e19d32", - "date": "2026-09-11", - "cpu": "Intel Xeon Processor 2.80GHz", - "runtime": ".NET 10.0.12 (10.0.12, 10.0.1226.42308)", - "baselineNs": 454.7423, - "runId": "local-seed", - "benchmarks": { - "ComparisonBenchmarks\u003CDecimal\u003E.CompareToInterface": { - "": { - "meanNs": 19.3255, - "allocatedBytes": 32 - } - }, - "ComparisonBenchmarks\u003CDouble\u003E.CompareToInterface": { - "": { - "meanNs": 13.9245, - "allocatedBytes": 24 - } - }, - "ComparisonBenchmarks\u003CPreciseNumber\u003E.CompareToInterface": { - "": { - "meanNs": 34.1165, - "allocatedBytes": 40 - } - }, - "ComparisonBenchmarks\u003CSingle\u003E.CompareToInterface": { - "": { - "meanNs": 13.375, - "allocatedBytes": 24 - } }, - "ConstructionBenchmarks\u003CDecimal\u003E.FromNauticalMile": { + "AbstractionCostBenchmarks\u003CDouble\u003E.BareAdd": { "": { - "meanNs": 9.3505, + "meanNs": 0.9943, "allocatedBytes": 0 } }, - "ConstructionBenchmarks\u003CDouble\u003E.FromNauticalMile": { + "AbstractionCostBenchmarks\u003CDouble\u003E.BareMultiply": { "": { - "meanNs": 3.3425, + "meanNs": 1.3638, "allocatedBytes": 0 } }, - "ConstructionBenchmarks\u003CPreciseNumber\u003E.FromNauticalMile": { - "": { - "meanNs": 444.181, - "allocatedBytes": 40 - } - }, - "ConstructionBenchmarks\u003CSingle\u003E.FromNauticalMile": { + "AbstractionCostBenchmarks\u003CDouble\u003E.QuantityAdd": { "": { - "meanNs": 1.0971, + "meanNs": 0.9946, "allocatedBytes": 0 } }, - "OperatorBenchmarks\u003CDecimal\u003E.LengthTimesLength": { + "AbstractionCostBenchmarks\u003CDouble\u003E.QuantityMultiply": { "": { - "meanNs": 49.8869, + "meanNs": 1.2734, "allocatedBytes": 0 } }, - "OperatorBenchmarks\u003CDouble\u003E.LengthTimesLength": { + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.BareAdd": { "": { - "meanNs": 0.5551, - "allocatedBytes": 0 + "meanNs": 96.1051, + "allocatedBytes": 64 } }, - "OperatorBenchmarks\u003CPreciseNumber\u003E.LengthTimesLength": { + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.BareMultiply": { "": { - "meanNs": 171.1742, - "allocatedBytes": 48 + "meanNs": 469.9444, + "allocatedBytes": 193 } }, - "OperatorBenchmarks\u003CSingle\u003E.LengthTimesLength": { + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.QuantityAdd": { "": { - "meanNs": 0.0061, - "allocatedBytes": 0 + "meanNs": 102.5185, + "allocatedBytes": 64 } }, - "UnitConversionBenchmarks\u003CDecimal\u003E.InNauticalMile": { + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.QuantityMultiply": { "": { - "meanNs": 73.8065, - "allocatedBytes": 0 + "meanNs": 485.4683, + "allocatedBytes": 193 } }, - "UnitConversionBenchmarks\u003CDouble\u003E.InNauticalMile": { + "AbstractionCostBenchmarks\u003CSingle\u003E.BareAdd": { "": { - "meanNs": 7.9266, + "meanNs": 0.9841, "allocatedBytes": 0 } }, - "UnitConversionBenchmarks\u003CPreciseNumber\u003E.InNauticalMile": { - "": { - "meanNs": 1027.7254, - "allocatedBytes": 232 - } - }, - "UnitConversionBenchmarks\u003CSingle\u003E.InNauticalMile": { + "AbstractionCostBenchmarks\u003CSingle\u003E.BareMultiply": { "": { - "meanNs": 7.0378, + "meanNs": 1.3542, "allocatedBytes": 0 } }, - "VectorBenchmarks\u003CDecimal\u003E.Length": { + "AbstractionCostBenchmarks\u003CSingle\u003E.QuantityAdd": { "": { - "meanNs": 164.2486, + "meanNs": 0.9872, "allocatedBytes": 0 } }, - "VectorBenchmarks\u003CDouble\u003E.Length": { + "AbstractionCostBenchmarks\u003CSingle\u003E.QuantityMultiply": { "": { - "meanNs": 0.4013, + "meanNs": 1.263, "allocatedBytes": 0 } }, - "VectorBenchmarks\u003CPreciseNumber\u003E.Length": { - "": { - "meanNs": 1808.3943, - "allocatedBytes": 312 - } - }, - "VectorBenchmarks\u003CSingle\u003E.Length": { - "": { - "meanNs": 0.772, - "allocatedBytes": 0 - } - } - } - }, - { - "version": "4.3.2", - "commit": "256def6", - "date": "2026-09-12", - "cpu": "Intel Xeon Processor 2.80GHz", - "runtime": ".NET 10.0.12 (10.0.12, 10.0.1226.42308)", - "baselineNs": 454.7423, - "runId": "local-seed", - "benchmarks": { "ComparisonBenchmarks\u003CDecimal\u003E.CompareToInterface": { "": { - "meanNs": 19.7476, + "meanNs": 19.7363, "allocatedBytes": 32 } }, "ComparisonBenchmarks\u003CDouble\u003E.CompareToInterface": { "": { - "meanNs": 14.1942, + "meanNs": 13.5563, "allocatedBytes": 24 } }, "ComparisonBenchmarks\u003CPreciseNumber\u003E.CompareToInterface": { "": { - "meanNs": 31.7734, + "meanNs": 33.8402, "allocatedBytes": 40 } }, "ComparisonBenchmarks\u003CSingle\u003E.CompareToInterface": { "": { - "meanNs": 14.6629, + "meanNs": 14.8623, "allocatedBytes": 24 } }, "ConstructionBenchmarks\u003CDecimal\u003E.FromNauticalMile": { "": { - "meanNs": 9.1464, + "meanNs": 9.0556, "allocatedBytes": 0 } }, "ConstructionBenchmarks\u003CDouble\u003E.FromNauticalMile": { "": { - "meanNs": 3.3107, + "meanNs": 2.132, "allocatedBytes": 0 } }, "ConstructionBenchmarks\u003CPreciseNumber\u003E.FromNauticalMile": { "": { - "meanNs": 439.0509, + "meanNs": 438.8794, "allocatedBytes": 40 } }, "ConstructionBenchmarks\u003CSingle\u003E.FromNauticalMile": { "": { - "meanNs": 1.0845, + "meanNs": 0.9488, "allocatedBytes": 0 } }, "OperatorBenchmarks\u003CDecimal\u003E.LengthTimesLength": { "": { - "meanNs": 49.6864, + "meanNs": 49.0148, "allocatedBytes": 0 } }, "OperatorBenchmarks\u003CDouble\u003E.LengthTimesLength": { "": { - "meanNs": 0.0064, + "meanNs": 0.0208, "allocatedBytes": 0 } }, "OperatorBenchmarks\u003CPreciseNumber\u003E.LengthTimesLength": { "": { - "meanNs": 153.0474, + "meanNs": 170.9443, "allocatedBytes": 48 } }, "OperatorBenchmarks\u003CSingle\u003E.LengthTimesLength": { "": { - "meanNs": 0.0215, + "meanNs": 0.4968, "allocatedBytes": 0 } }, "UnitConversionBenchmarks\u003CDecimal\u003E.InNauticalMile": { "": { - "meanNs": 73.5654, + "meanNs": 71.0179, "allocatedBytes": 0 } }, "UnitConversionBenchmarks\u003CDouble\u003E.InNauticalMile": { "": { - "meanNs": 6.9238, + "meanNs": 7.4828, "allocatedBytes": 0 } }, "UnitConversionBenchmarks\u003CPreciseNumber\u003E.InNauticalMile": { "": { - "meanNs": 999.566, + "meanNs": 996.3263, "allocatedBytes": 232 } }, "UnitConversionBenchmarks\u003CSingle\u003E.InNauticalMile": { "": { - "meanNs": 7.4833, + "meanNs": 6.9198, "allocatedBytes": 0 } }, "VectorBenchmarks\u003CDecimal\u003E.Length": { "": { - "meanNs": 164.8533, + "meanNs": 173.0214, "allocatedBytes": 0 } }, "VectorBenchmarks\u003CDouble\u003E.Length": { "": { - "meanNs": 0.4858, + "meanNs": 0.3585, "allocatedBytes": 0 } }, "VectorBenchmarks\u003CPreciseNumber\u003E.Length": { "": { - "meanNs": 1791.8562, + "meanNs": 2228.5622, "allocatedBytes": 312 } }, "VectorBenchmarks\u003CSingle\u003E.Length": { "": { - "meanNs": 0.83, - "allocatedBytes": 0 - } - } - } - }, - { - "version": "5.0.0", - "commit": "bb69de0", - "date": "2026-09-12", - "cpu": "Intel Xeon Processor 2.80GHz", - "runtime": ".NET 10.0.12 (10.0.12, 10.0.1226.42308)", - "baselineNs": 454.7423, - "runId": "local-seed", - "benchmarks": { - "ComparisonBenchmarks\u003CDecimal\u003E.CompareToInterface": { - "": { - "meanNs": 17.0531, - "allocatedBytes": 32 - } - }, - "ComparisonBenchmarks\u003CDouble\u003E.CompareToInterface": { - "": { - "meanNs": 14.1983, - "allocatedBytes": 24 - } - }, - "ComparisonBenchmarks\u003CPreciseNumber\u003E.CompareToInterface": { - "": { - "meanNs": 27.5663, - "allocatedBytes": 40 - } - }, - "ComparisonBenchmarks\u003CSingle\u003E.CompareToInterface": { - "": { - "meanNs": 12.3376, - "allocatedBytes": 24 - } - }, - "ConstructionBenchmarks\u003CDecimal\u003E.FromNauticalMile": { - "": { - "meanNs": 9.1429, - "allocatedBytes": 0 - } - }, - "ConstructionBenchmarks\u003CDouble\u003E.FromNauticalMile": { - "": { - "meanNs": 2.1024, - "allocatedBytes": 0 - } - }, - "ConstructionBenchmarks\u003CPreciseNumber\u003E.FromNauticalMile": { - "": { - "meanNs": 440.8756, - "allocatedBytes": 40 - } - }, - "ConstructionBenchmarks\u003CSingle\u003E.FromNauticalMile": { - "": { - "meanNs": 1.1355, - "allocatedBytes": 0 - } - }, - "OperatorBenchmarks\u003CDecimal\u003E.LengthTimesLength": { - "": { - "meanNs": 48.7206, - "allocatedBytes": 0 - } - }, - "OperatorBenchmarks\u003CDouble\u003E.LengthTimesLength": { - "": { - "meanNs": 0.001, - "allocatedBytes": 0 - } - }, - "OperatorBenchmarks\u003CPreciseNumber\u003E.LengthTimesLength": { - "": { - "meanNs": 167.6413, - "allocatedBytes": 48 - } - }, - "OperatorBenchmarks\u003CSingle\u003E.LengthTimesLength": { - "": { - "meanNs": 0.5091, - "allocatedBytes": 0 - } - }, - "UnitConversionBenchmarks\u003CDecimal\u003E.InNauticalMile": { - "": { - "meanNs": 76.0165, - "allocatedBytes": 0 - } - }, - "UnitConversionBenchmarks\u003CDouble\u003E.InNauticalMile": { - "": { - "meanNs": 6.8443, - "allocatedBytes": 0 - } - }, - "UnitConversionBenchmarks\u003CPreciseNumber\u003E.InNauticalMile": { - "": { - "meanNs": 1014.094, - "allocatedBytes": 232 - } - }, - "UnitConversionBenchmarks\u003CSingle\u003E.InNauticalMile": { - "": { - "meanNs": 7.7742, - "allocatedBytes": 0 - } - }, - "VectorBenchmarks\u003CDecimal\u003E.Length": { - "": { - "meanNs": 161.0405, - "allocatedBytes": 0 - } - }, - "VectorBenchmarks\u003CDouble\u003E.Length": { - "": { - "meanNs": 0.4173, - "allocatedBytes": 0 - } - }, - "VectorBenchmarks\u003CPreciseNumber\u003E.Length": { - "": { - "meanNs": 1778.1463, - "allocatedBytes": 312 - } - }, - "VectorBenchmarks\u003CSingle\u003E.Length": { - "": { - "meanNs": 0.6495, - "allocatedBytes": 0 - } - } - } - }, - { - "version": "5.1.0", - "commit": "4c71e14", - "date": "2026-09-13", - "cpu": "Intel Xeon Processor 2.80GHz", - "runtime": ".NET 10.0.12 (10.0.12, 10.0.1226.42308)", - "baselineNs": 454.7423, - "runId": "local-seed", - "benchmarks": { - "ComparisonBenchmarks\u003CDecimal\u003E.CompareToInterface": { - "": { - "meanNs": 17.2642, - "allocatedBytes": 32 - } - }, - "ComparisonBenchmarks\u003CDouble\u003E.CompareToInterface": { - "": { - "meanNs": 14.6504, - "allocatedBytes": 24 - } - }, - "ComparisonBenchmarks\u003CPreciseNumber\u003E.CompareToInterface": { - "": { - "meanNs": 28.4428, - "allocatedBytes": 40 - } - }, - "ComparisonBenchmarks\u003CSingle\u003E.CompareToInterface": { - "": { - "meanNs": 14.593, - "allocatedBytes": 24 - } - }, - "ConstructionBenchmarks\u003CDecimal\u003E.FromNauticalMile": { - "": { - "meanNs": 9.0442, - "allocatedBytes": 0 - } - }, - "ConstructionBenchmarks\u003CDouble\u003E.FromNauticalMile": { - "": { - "meanNs": 2.1058, - "allocatedBytes": 0 - } - }, - "ConstructionBenchmarks\u003CPreciseNumber\u003E.FromNauticalMile": { - "": { - "meanNs": 443.6043, - "allocatedBytes": 40 - } - }, - "ConstructionBenchmarks\u003CSingle\u003E.FromNauticalMile": { - "": { - "meanNs": 1.047, - "allocatedBytes": 0 - } - }, - "OperatorBenchmarks\u003CDecimal\u003E.LengthTimesLength": { - "": { - "meanNs": 49.4833, - "allocatedBytes": 0 - } - }, - "OperatorBenchmarks\u003CDouble\u003E.LengthTimesLength": { - "": { - "meanNs": 0.0023, - "allocatedBytes": 0 - } - }, - "OperatorBenchmarks\u003CPreciseNumber\u003E.LengthTimesLength": { - "": { - "meanNs": 168.0931, - "allocatedBytes": 48 - } - }, - "OperatorBenchmarks\u003CSingle\u003E.LengthTimesLength": { - "": { - "meanNs": 0.0017, - "allocatedBytes": 0 - } - }, - "UnitConversionBenchmarks\u003CDecimal\u003E.InNauticalMile": { - "": { - "meanNs": 70.3008, - "allocatedBytes": 0 - } - }, - "UnitConversionBenchmarks\u003CDouble\u003E.InNauticalMile": { - "": { - "meanNs": 6.8747, - "allocatedBytes": 0 - } - }, - "UnitConversionBenchmarks\u003CPreciseNumber\u003E.InNauticalMile": { - "": { - "meanNs": 997.1396, - "allocatedBytes": 232 - } - }, - "UnitConversionBenchmarks\u003CSingle\u003E.InNauticalMile": { - "": { - "meanNs": 8.6266, - "allocatedBytes": 0 - } - }, - "VectorBenchmarks\u003CDecimal\u003E.Length": { - "": { - "meanNs": 169.2199, - "allocatedBytes": 0 - } - }, - "VectorBenchmarks\u003CDouble\u003E.Length": { - "": { - "meanNs": 0.3754, - "allocatedBytes": 0 - } - }, - "VectorBenchmarks\u003CPreciseNumber\u003E.Length": { - "": { - "meanNs": 1780.1261, - "allocatedBytes": 312 - } - }, - "VectorBenchmarks\u003CSingle\u003E.Length": { - "": { - "meanNs": 0.7037, - "allocatedBytes": 0 - } - } - } - }, - { - "version": "5.2.0", - "commit": "eda9fc8", - "date": "2026-09-13", - "cpu": "Intel Xeon Processor 2.80GHz", - "runtime": ".NET 10.0.12 (10.0.12, 10.0.1226.42308)", - "baselineNs": 454.7423, - "runId": "local-seed", - "benchmarks": { - "ComparisonBenchmarks\u003CDecimal\u003E.CompareToInterface": { - "": { - "meanNs": 19.0621, - "allocatedBytes": 32 - } - }, - "ComparisonBenchmarks\u003CDouble\u003E.CompareToInterface": { - "": { - "meanNs": 13.6742, - "allocatedBytes": 24 - } - }, - "ComparisonBenchmarks\u003CPreciseNumber\u003E.CompareToInterface": { - "": { - "meanNs": 28.8963, - "allocatedBytes": 40 - } - }, - "ComparisonBenchmarks\u003CSingle\u003E.CompareToInterface": { - "": { - "meanNs": 13.1918, - "allocatedBytes": 24 - } - }, - "ConstructionBenchmarks\u003CDecimal\u003E.FromNauticalMile": { - "": { - "meanNs": 7.6477, - "allocatedBytes": 0 - } - }, - "ConstructionBenchmarks\u003CDouble\u003E.FromNauticalMile": { - "": { - "meanNs": 2.035, - "allocatedBytes": 0 - } - }, - "ConstructionBenchmarks\u003CPreciseNumber\u003E.FromNauticalMile": { - "": { - "meanNs": 106.7759, - "allocatedBytes": 40 - } - }, - "ConstructionBenchmarks\u003CSingle\u003E.FromNauticalMile": { - "": { - "meanNs": 0.8308, - "allocatedBytes": 0 - } - }, - "OperatorBenchmarks\u003CDecimal\u003E.LengthTimesLength": { - "": { - "meanNs": 49.7014, - "allocatedBytes": 0 - } - }, - "OperatorBenchmarks\u003CDouble\u003E.LengthTimesLength": { - "": { - "meanNs": 0.0023, - "allocatedBytes": 0 - } - }, - "OperatorBenchmarks\u003CPreciseNumber\u003E.LengthTimesLength": { - "": { - "meanNs": 175.7197, - "allocatedBytes": 48 - } - }, - "OperatorBenchmarks\u003CSingle\u003E.LengthTimesLength": { - "": { - "meanNs": 0.5194, - "allocatedBytes": 0 - } - }, - "UnitConversionBenchmarks\u003CDecimal\u003E.InNauticalMile": { - "": { - "meanNs": 79.1666, - "allocatedBytes": 0 - } - }, - "UnitConversionBenchmarks\u003CDouble\u003E.InNauticalMile": { - "": { - "meanNs": 22.796, - "allocatedBytes": 0 - } - }, - "UnitConversionBenchmarks\u003CPreciseNumber\u003E.InNauticalMile": { - "": { - "meanNs": 637.7155, - "allocatedBytes": 232 - } - }, - "UnitConversionBenchmarks\u003CSingle\u003E.InNauticalMile": { - "": { - "meanNs": 19.5547, - "allocatedBytes": 0 - } - }, - "VectorBenchmarks\u003CDecimal\u003E.Length": { - "": { - "meanNs": 506.5822, - "allocatedBytes": 0 - } - }, - "VectorBenchmarks\u003CDouble\u003E.Length": { - "": { - "meanNs": 0.9443, - "allocatedBytes": 0 - } - }, - "VectorBenchmarks\u003CPreciseNumber\u003E.Length": { - "": { - "meanNs": 6588.3068, - "allocatedBytes": 1760 - } - }, - "VectorBenchmarks\u003CSingle\u003E.Length": { - "": { - "meanNs": 0.9528, - "allocatedBytes": 0 - } - } - } - }, - { - "version": "5.2.4", - "commit": "cbc914c", - "date": "2026-09-14", - "cpu": "Intel Xeon Processor 2.80GHz", - "runtime": ".NET 10.0.12 (10.0.12, 10.0.1226.42308)", - "baselineNs": 454.7423, - "runId": "local-seed", - "benchmarks": { - "ComparisonBenchmarks\u003CDecimal\u003E.CompareToInterface": { - "": { - "meanNs": 19.0401, - "allocatedBytes": 32 - } - }, - "ComparisonBenchmarks\u003CDouble\u003E.CompareToInterface": { - "": { - "meanNs": 13.9626, - "allocatedBytes": 24 - } - }, - "ComparisonBenchmarks\u003CPreciseNumber\u003E.CompareToInterface": { - "": { - "meanNs": 30.4436, - "allocatedBytes": 40 - } - }, - "ComparisonBenchmarks\u003CSingle\u003E.CompareToInterface": { - "": { - "meanNs": 15.0078, - "allocatedBytes": 24 - } - }, - "ConstructionBenchmarks\u003CDecimal\u003E.FromNauticalMile": { - "": { - "meanNs": 15.3305, - "allocatedBytes": 0 - } - }, - "ConstructionBenchmarks\u003CDouble\u003E.FromNauticalMile": { - "": { - "meanNs": 3.3693, - "allocatedBytes": 0 - } - }, - "ConstructionBenchmarks\u003CPreciseNumber\u003E.FromNauticalMile": { - "": { - "meanNs": 119.6968, - "allocatedBytes": 40 - } - }, - "ConstructionBenchmarks\u003CSingle\u003E.FromNauticalMile": { - "": { - "meanNs": 2.0236, - "allocatedBytes": 0 - } - }, - "OperatorBenchmarks\u003CDecimal\u003E.LengthTimesLength": { - "": { - "meanNs": 48.7248, - "allocatedBytes": 0 - } - }, - "OperatorBenchmarks\u003CDouble\u003E.LengthTimesLength": { - "": { - "meanNs": 0.0535, - "allocatedBytes": 0 - } - }, - "OperatorBenchmarks\u003CPreciseNumber\u003E.LengthTimesLength": { - "": { - "meanNs": 168.3563, - "allocatedBytes": 48 - } - }, - "OperatorBenchmarks\u003CSingle\u003E.LengthTimesLength": { - "": { - "meanNs": 0.0685, - "allocatedBytes": 0 - } - }, - "UnitConversionBenchmarks\u003CDecimal\u003E.InNauticalMile": { - "": { - "meanNs": 81.7809, - "allocatedBytes": 0 - } - }, - "UnitConversionBenchmarks\u003CDouble\u003E.InNauticalMile": { - "": { - "meanNs": 20.0893, - "allocatedBytes": 0 - } - }, - "UnitConversionBenchmarks\u003CPreciseNumber\u003E.InNauticalMile": { - "": { - "meanNs": 634.1803, - "allocatedBytes": 232 - } - }, - "UnitConversionBenchmarks\u003CSingle\u003E.InNauticalMile": { - "": { - "meanNs": 17.9519, - "allocatedBytes": 0 - } - }, - "VectorBenchmarks\u003CDecimal\u003E.Length": { - "": { - "meanNs": 515.3732, - "allocatedBytes": 0 - } - }, - "VectorBenchmarks\u003CDouble\u003E.Length": { - "": { - "meanNs": 0.8839, - "allocatedBytes": 0 - } - }, - "VectorBenchmarks\u003CPreciseNumber\u003E.Length": { - "": { - "meanNs": 6395.2321, - "allocatedBytes": 1760 - } - }, - "VectorBenchmarks\u003CSingle\u003E.Length": { - "": { - "meanNs": 1.0075, - "allocatedBytes": 0 - } - } - } - }, - { - "version": "5.3.2", - "commit": "2a3e53b", - "date": "2026-09-16", - "cpu": "Intel Xeon Processor 2.80GHz", - "runtime": ".NET 10.0.12 (10.0.12, 10.0.1226.42308)", - "baselineNs": 454.7423, - "runId": "local-seed", - "benchmarks": { - "ComparisonBenchmarks\u003CDecimal\u003E.CompareToInterface": { - "": { - "meanNs": 18.7366, - "allocatedBytes": 32 - } - }, - "ComparisonBenchmarks\u003CDouble\u003E.CompareToInterface": { - "": { - "meanNs": 13.152, - "allocatedBytes": 24 - } - }, - "ComparisonBenchmarks\u003CPreciseNumber\u003E.CompareToInterface": { - "": { - "meanNs": 28.5365, - "allocatedBytes": 40 - } - }, - "ComparisonBenchmarks\u003CSingle\u003E.CompareToInterface": { - "": { - "meanNs": 13.502, - "allocatedBytes": 24 - } - }, - "ConstructionBenchmarks\u003CDecimal\u003E.FromNauticalMile": { - "": { - "meanNs": 15.5335, - "allocatedBytes": 0 - } - }, - "ConstructionBenchmarks\u003CDouble\u003E.FromNauticalMile": { - "": { - "meanNs": 3.3758, - "allocatedBytes": 0 - } - }, - "ConstructionBenchmarks\u003CPreciseNumber\u003E.FromNauticalMile": { - "": { - "meanNs": 119.0305, - "allocatedBytes": 40 - } - }, - "ConstructionBenchmarks\u003CSingle\u003E.FromNauticalMile": { - "": { - "meanNs": 2.0081, - "allocatedBytes": 0 - } - }, - "OperatorBenchmarks\u003CDecimal\u003E.LengthTimesLength": { - "": { - "meanNs": 48.593, - "allocatedBytes": 0 - } - }, - "OperatorBenchmarks\u003CDouble\u003E.LengthTimesLength": { - "": { - "meanNs": 0.5216, - "allocatedBytes": 0 - } - }, - "OperatorBenchmarks\u003CPreciseNumber\u003E.LengthTimesLength": { - "": { - "meanNs": 169.8841, - "allocatedBytes": 48 - } - }, - "OperatorBenchmarks\u003CSingle\u003E.LengthTimesLength": { - "": { - "meanNs": 0.0431, - "allocatedBytes": 0 - } - }, - "UnitConversionBenchmarks\u003CDecimal\u003E.InNauticalMile": { - "": { - "meanNs": 82.7255, - "allocatedBytes": 0 - } - }, - "UnitConversionBenchmarks\u003CDouble\u003E.InNauticalMile": { - "": { - "meanNs": 17.6686, - "allocatedBytes": 0 - } - }, - "UnitConversionBenchmarks\u003CPreciseNumber\u003E.InNauticalMile": { - "": { - "meanNs": 631.3755, - "allocatedBytes": 232 - } - }, - "UnitConversionBenchmarks\u003CSingle\u003E.InNauticalMile": { - "": { - "meanNs": 18.8093, - "allocatedBytes": 0 - } - }, - "VectorBenchmarks\u003CDecimal\u003E.Length": { - "": { - "meanNs": 512.9149, - "allocatedBytes": 0 - } - }, - "VectorBenchmarks\u003CDouble\u003E.Length": { - "": { - "meanNs": 1.0452, - "allocatedBytes": 0 - } - }, - "VectorBenchmarks\u003CPreciseNumber\u003E.Length": { - "": { - "meanNs": 6547.0307, - "allocatedBytes": 1760 - } - }, - "VectorBenchmarks\u003CSingle\u003E.Length": { - "": { - "meanNs": 1.0098, + "meanNs": 0.762, "allocatedBytes": 0 } } From eabf98ef0169ee811242704491e413e5889c6661 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 16 Sep 2026 12:01:48 +0000 Subject: [PATCH 3/3] Seed the abstraction-cost pair across every release [patch] Ten releases measured in one pass against a single reference reading, so the ratios are comparable as they stand. The wrapper over the bare storage type: add(dbl) mul(dbl) mul(dec) mul(prec) 3.3.1 27.84 56.37 2.27 1.33 4.0.0 1.02 0.93 0.86 1.04 4.3.2 1.00 0.94 0.86 1.05 5.0.0 1.01 0.93 0.91 1.02 5.3.2 0.99 0.95 0.86 1.03 4.0 is where the abstraction became free. Before it a quantity was a class, so every operation allocated an object and a Length add cost 28 times a bare double add; six releases since have held it at 1. The spread across the 3.3.1 row is why this suite is parameterised by storage type rather than measured at one. The same wrapper, in the same release, cost 56x over a double and 1.33x over a PreciseNumber: an allocation per operation is crushing when T is a machine instruction and invisible when T is already doing arbitrary-precision arithmetic. Measured at one storage type the 4.0 change would have looked like anything between a rewrite and a rounding error. A ratio below 1 is not the quantity beating the number inside it; wrapping cannot remove work. Where it is stable rather than scattered, and decimal multiply sits at about 0.86 in every release, it is code layout rather than noise -- the two loops compile to slightly different orderings and the wrapped one lands better for that type's software multiply. The column reads as no measurable wrapper cost, not as a direction. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_017jrnV7N94UGL8fDRRE8Xt8 --- Semantics.Benchmarks/README.md | 29 +- docs/benchmarks/history.json | 1816 ++++++++++++++++++++++++++ docs/benchmarks/performance-dark.svg | 261 ++-- docs/benchmarks/performance.svg | 261 ++-- 4 files changed, 2166 insertions(+), 201 deletions(-) diff --git a/Semantics.Benchmarks/README.md b/Semantics.Benchmarks/README.md index 225f2ab..083c9b5 100644 --- a/Semantics.Benchmarks/README.md +++ b/Semantics.Benchmarks/README.md @@ -97,9 +97,32 @@ Each pair runs identical arithmetic on `T` and on quantities over `T`, with the | `decimal` | 1.04 | 0.90 | none either side | | `PreciseNumber` | 1.03 | 1.03 | 193 B either side, ratio 1.00 | -The wrapper is free. Read the ratios below 1.00 as noise and code layout rather than as the quantity -being faster than the number inside it — the spread across three short-run iterations covers that -much, and there is no mechanism by which it could be. +The wrapper is free. A ratio below 1.00 is **not** the quantity beating the number inside it — +wrapping cannot remove work, and there is no mechanism by which it could. Where such a ratio is +stable rather than scattered, and `decimal` multiply is stable at about 0.86 across every release +measured, it is code layout: the two loops compile to slightly different orderings and the wrapped +one happens to land better for that type's software multiply. Read the whole column as "no +measurable wrapper cost" rather than as a direction. + +### It was not always free, and the chart says when + +`docs/benchmarks/` now carries this per release, and the answer before 4.0 is a different one +entirely. In 3.3.1, when a quantity was a class rather than a `readonly record struct`: + +| storage | `Add` | `Multiply` | +|---|---|---| +| `double` | **27.84** | **56.37** | +| `decimal` | — | 2.27 | +| `PreciseNumber` | — | 1.33 | + +Every operation allocated an object, so a `Length` add cost 28 times a bare `double` add. +4.0 took that to 1.00 and six releases have held it there. + +The spread across that row is the reason this suite is parameterised by storage type at all: the +same wrapper, in the same release, cost 56× over a `double` and 1.33× over a `PreciseNumber`. An +allocation per operation is crushing when `T` is a machine instruction and invisible when `T` is +already doing arbitrary-precision arithmetic. Measured at one storage type, the 4.0 change would +have looked like anything between a rewrite and a rounding error. The `PreciseNumber` row is the one that says it most precisely, because it is the only storage type here that allocates at all: **the allocation ratio is exactly 1.00**. Every byte belongs to the diff --git a/docs/benchmarks/history.json b/docs/benchmarks/history.json index 22848e7..294d045 100644 --- a/docs/benchmarks/history.json +++ b/docs/benchmarks/history.json @@ -1,6 +1,233 @@ { "schemaVersion": 1, "entries": [ + { + "version": "3.3.1", + "commit": "fffa086", + "date": "2026-09-09", + "cpu": "Intel Xeon Processor 2.80GHz", + "runtime": ".NET 10.0.12 (10.0.12, 10.0.1226.42308)", + "baselineNs": 453.7426, + "runId": "local-seed", + "benchmarks": { + "AbstractionCostBenchmarks\u003CDecimal\u003E.BareAdd": { + "": { + "meanNs": 8.687, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDecimal\u003E.BareMultiply": { + "": { + "meanNs": 82.0312, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDecimal\u003E.QuantityAdd": { + "": { + "meanNs": 39.4121, + "allocatedBytes": 64 + } + }, + "AbstractionCostBenchmarks\u003CDecimal\u003E.QuantityMultiply": { + "": { + "meanNs": 186.5101, + "allocatedBytes": 192 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.BareAdd": { + "": { + "meanNs": 0.9894, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.BareMultiply": { + "": { + "meanNs": 1.3585, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.QuantityAdd": { + "": { + "meanNs": 27.5482, + "allocatedBytes": 48 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.QuantityMultiply": { + "": { + "meanNs": 76.5788, + "allocatedBytes": 144 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.BareAdd": { + "": { + "meanNs": 98.6858, + "allocatedBytes": 64 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.BareMultiply": { + "": { + "meanNs": 470.7615, + "allocatedBytes": 193 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.QuantityAdd": { + "": { + "meanNs": 164.6354, + "allocatedBytes": 144 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.QuantityMultiply": { + "": { + "meanNs": 626.2963, + "allocatedBytes": 433 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.BareAdd": { + "": { + "meanNs": 1.0001, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.BareMultiply": { + "": { + "meanNs": 1.3697, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.QuantityAdd": { + "": { + "meanNs": 26.7098, + "allocatedBytes": 48 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.QuantityMultiply": { + "": { + "meanNs": 83.8432, + "allocatedBytes": 144 + } + }, + "ComparisonBenchmarks\u003CDecimal\u003E.CompareToInterface": { + "": { + "meanNs": 8.5663, + "allocatedBytes": 0 + } + }, + "ComparisonBenchmarks\u003CDouble\u003E.CompareToInterface": { + "": { + "meanNs": 4.4442, + "allocatedBytes": 0 + } + }, + "ComparisonBenchmarks\u003CPreciseNumber\u003E.CompareToInterface": { + "": { + "meanNs": 11.5848, + "allocatedBytes": 0 + } + }, + "ComparisonBenchmarks\u003CSingle\u003E.CompareToInterface": { + "": { + "meanNs": 5.1784, + "allocatedBytes": 0 + } + }, + "ConstructionBenchmarks\u003CDecimal\u003E.FromNauticalMile": { + "": { + "meanNs": 46.7546, + "allocatedBytes": 64 + } + }, + "ConstructionBenchmarks\u003CDouble\u003E.FromNauticalMile": { + "": { + "meanNs": 30.6769, + "allocatedBytes": 48 + } + }, + "ConstructionBenchmarks\u003CPreciseNumber\u003E.FromNauticalMile": { + "": { + "meanNs": 512.979, + "allocatedBytes": 120 + } + }, + "ConstructionBenchmarks\u003CSingle\u003E.FromNauticalMile": { + "": { + "meanNs": 29.3538, + "allocatedBytes": 48 + } + }, + "OperatorBenchmarks\u003CDecimal\u003E.LengthTimesLength": { + "": { + "meanNs": 81.617, + "allocatedBytes": 64 + } + }, + "OperatorBenchmarks\u003CDouble\u003E.LengthTimesLength": { + "": { + "meanNs": 29.4845, + "allocatedBytes": 48 + } + }, + "OperatorBenchmarks\u003CPreciseNumber\u003E.LengthTimesLength": { + "": { + "meanNs": 230.0481, + "allocatedBytes": 128 + } + }, + "OperatorBenchmarks\u003CSingle\u003E.LengthTimesLength": { + "": { + "meanNs": 27.9655, + "allocatedBytes": 48 + } + }, + "UnitConversionBenchmarks\u003CDecimal\u003E.InNauticalMile": { + "": { + "meanNs": 70.8902, + "allocatedBytes": 0 + } + }, + "UnitConversionBenchmarks\u003CDouble\u003E.InNauticalMile": { + "": { + "meanNs": 6.953, + "allocatedBytes": 0 + } + }, + "UnitConversionBenchmarks\u003CPreciseNumber\u003E.InNauticalMile": { + "": { + "meanNs": 1000.3666, + "allocatedBytes": 232 + } + }, + "UnitConversionBenchmarks\u003CSingle\u003E.InNauticalMile": { + "": { + "meanNs": 7.1579, + "allocatedBytes": 0 + } + }, + "VectorBenchmarks\u003CDecimal\u003E.Length": { + "": { + "meanNs": 162.7914, + "allocatedBytes": 0 + } + }, + "VectorBenchmarks\u003CDouble\u003E.Length": { + "": { + "meanNs": 0.4212, + "allocatedBytes": 0 + } + }, + "VectorBenchmarks\u003CPreciseNumber\u003E.Length": { + "": { + "meanNs": 1841.7999, + "allocatedBytes": 312 + } + }, + "VectorBenchmarks\u003CSingle\u003E.Length": { + "": { + "meanNs": 0.832, + "allocatedBytes": 0 + } + } + } + }, { "version": "4.0.0", "commit": "496d895", @@ -454,6 +681,1595 @@ } } } + }, + { + "version": "4.2.0", + "commit": "5e19d32", + "date": "2026-09-11", + "cpu": "Intel Xeon Processor 2.80GHz", + "runtime": ".NET 10.0.12 (10.0.12, 10.0.1226.42308)", + "baselineNs": 453.7426, + "runId": "local-seed", + "benchmarks": { + "AbstractionCostBenchmarks\u003CDecimal\u003E.BareAdd": { + "": { + "meanNs": 8.68, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDecimal\u003E.BareMultiply": { + "": { + "meanNs": 84.0068, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDecimal\u003E.QuantityAdd": { + "": { + "meanNs": 9.2045, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDecimal\u003E.QuantityMultiply": { + "": { + "meanNs": 71.8109, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.BareAdd": { + "": { + "meanNs": 1.0091, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.BareMultiply": { + "": { + "meanNs": 1.3738, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.QuantityAdd": { + "": { + "meanNs": 0.9941, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.QuantityMultiply": { + "": { + "meanNs": 1.2689, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.BareAdd": { + "": { + "meanNs": 101.4151, + "allocatedBytes": 64 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.BareMultiply": { + "": { + "meanNs": 477.1438, + "allocatedBytes": 193 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.QuantityAdd": { + "": { + "meanNs": 102.5898, + "allocatedBytes": 64 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.QuantityMultiply": { + "": { + "meanNs": 487.1803, + "allocatedBytes": 193 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.BareAdd": { + "": { + "meanNs": 0.9839, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.BareMultiply": { + "": { + "meanNs": 1.3549, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.QuantityAdd": { + "": { + "meanNs": 0.9852, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.QuantityMultiply": { + "": { + "meanNs": 1.2715, + "allocatedBytes": 0 + } + }, + "ComparisonBenchmarks\u003CDecimal\u003E.CompareToInterface": { + "": { + "meanNs": 19.1929, + "allocatedBytes": 32 + } + }, + "ComparisonBenchmarks\u003CDouble\u003E.CompareToInterface": { + "": { + "meanNs": 13.5433, + "allocatedBytes": 24 + } + }, + "ComparisonBenchmarks\u003CPreciseNumber\u003E.CompareToInterface": { + "": { + "meanNs": 33.9785, + "allocatedBytes": 40 + } + }, + "ComparisonBenchmarks\u003CSingle\u003E.CompareToInterface": { + "": { + "meanNs": 13.297, + "allocatedBytes": 24 + } + }, + "ConstructionBenchmarks\u003CDecimal\u003E.FromNauticalMile": { + "": { + "meanNs": 9.3677, + "allocatedBytes": 0 + } + }, + "ConstructionBenchmarks\u003CDouble\u003E.FromNauticalMile": { + "": { + "meanNs": 2.079, + "allocatedBytes": 0 + } + }, + "ConstructionBenchmarks\u003CPreciseNumber\u003E.FromNauticalMile": { + "": { + "meanNs": 443.2349, + "allocatedBytes": 40 + } + }, + "ConstructionBenchmarks\u003CSingle\u003E.FromNauticalMile": { + "": { + "meanNs": 0.9476, + "allocatedBytes": 0 + } + }, + "OperatorBenchmarks\u003CDecimal\u003E.LengthTimesLength": { + "": { + "meanNs": 48.5374, + "allocatedBytes": 0 + } + }, + "OperatorBenchmarks\u003CDouble\u003E.LengthTimesLength": { + "": { + "meanNs": 0.0001, + "allocatedBytes": 0 + } + }, + "OperatorBenchmarks\u003CPreciseNumber\u003E.LengthTimesLength": { + "": { + "meanNs": 168.0467, + "allocatedBytes": 48 + } + }, + "OperatorBenchmarks\u003CSingle\u003E.LengthTimesLength": { + "": { + "meanNs": 0.5161, + "allocatedBytes": 0 + } + }, + "UnitConversionBenchmarks\u003CDecimal\u003E.InNauticalMile": { + "": { + "meanNs": 72.5976, + "allocatedBytes": 0 + } + }, + "UnitConversionBenchmarks\u003CDouble\u003E.InNauticalMile": { + "": { + "meanNs": 7.2387, + "allocatedBytes": 0 + } + }, + "UnitConversionBenchmarks\u003CPreciseNumber\u003E.InNauticalMile": { + "": { + "meanNs": 993.1048, + "allocatedBytes": 232 + } + }, + "UnitConversionBenchmarks\u003CSingle\u003E.InNauticalMile": { + "": { + "meanNs": 7.3354, + "allocatedBytes": 0 + } + }, + "VectorBenchmarks\u003CDecimal\u003E.Length": { + "": { + "meanNs": 164.0669, + "allocatedBytes": 0 + } + }, + "VectorBenchmarks\u003CDouble\u003E.Length": { + "": { + "meanNs": 0.377, + "allocatedBytes": 0 + } + }, + "VectorBenchmarks\u003CPreciseNumber\u003E.Length": { + "": { + "meanNs": 1767.0203, + "allocatedBytes": 312 + } + }, + "VectorBenchmarks\u003CSingle\u003E.Length": { + "": { + "meanNs": 0.7242, + "allocatedBytes": 0 + } + } + } + }, + { + "version": "4.3.2", + "commit": "256def6", + "date": "2026-09-12", + "cpu": "Intel Xeon Processor 2.80GHz", + "runtime": ".NET 10.0.12 (10.0.12, 10.0.1226.42308)", + "baselineNs": 453.7426, + "runId": "local-seed", + "benchmarks": { + "AbstractionCostBenchmarks\u003CDecimal\u003E.BareAdd": { + "": { + "meanNs": 9.0038, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDecimal\u003E.BareMultiply": { + "": { + "meanNs": 82.6392, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDecimal\u003E.QuantityAdd": { + "": { + "meanNs": 9.0283, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDecimal\u003E.QuantityMultiply": { + "": { + "meanNs": 71.2162, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.BareAdd": { + "": { + "meanNs": 0.9897, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.BareMultiply": { + "": { + "meanNs": 1.364, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.QuantityAdd": { + "": { + "meanNs": 0.9848, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.QuantityMultiply": { + "": { + "meanNs": 1.2799, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.BareAdd": { + "": { + "meanNs": 99.9605, + "allocatedBytes": 64 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.BareMultiply": { + "": { + "meanNs": 459.8805, + "allocatedBytes": 193 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.QuantityAdd": { + "": { + "meanNs": 98.1587, + "allocatedBytes": 64 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.QuantityMultiply": { + "": { + "meanNs": 484.7496, + "allocatedBytes": 193 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.BareAdd": { + "": { + "meanNs": 0.9964, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.BareMultiply": { + "": { + "meanNs": 1.3703, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.QuantityAdd": { + "": { + "meanNs": 0.9913, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.QuantityMultiply": { + "": { + "meanNs": 1.2788, + "allocatedBytes": 0 + } + }, + "ComparisonBenchmarks\u003CDecimal\u003E.CompareToInterface": { + "": { + "meanNs": 18.5495, + "allocatedBytes": 32 + } + }, + "ComparisonBenchmarks\u003CDouble\u003E.CompareToInterface": { + "": { + "meanNs": 14.2511, + "allocatedBytes": 24 + } + }, + "ComparisonBenchmarks\u003CPreciseNumber\u003E.CompareToInterface": { + "": { + "meanNs": 30.0153, + "allocatedBytes": 40 + } + }, + "ComparisonBenchmarks\u003CSingle\u003E.CompareToInterface": { + "": { + "meanNs": 14.8488, + "allocatedBytes": 24 + } + }, + "ConstructionBenchmarks\u003CDecimal\u003E.FromNauticalMile": { + "": { + "meanNs": 9.1867, + "allocatedBytes": 0 + } + }, + "ConstructionBenchmarks\u003CDouble\u003E.FromNauticalMile": { + "": { + "meanNs": 2.0466, + "allocatedBytes": 0 + } + }, + "ConstructionBenchmarks\u003CPreciseNumber\u003E.FromNauticalMile": { + "": { + "meanNs": 440.2176, + "allocatedBytes": 40 + } + }, + "ConstructionBenchmarks\u003CSingle\u003E.FromNauticalMile": { + "": { + "meanNs": 0.9164, + "allocatedBytes": 0 + } + }, + "OperatorBenchmarks\u003CDecimal\u003E.LengthTimesLength": { + "": { + "meanNs": 50.5161, + "allocatedBytes": 0 + } + }, + "OperatorBenchmarks\u003CDouble\u003E.LengthTimesLength": { + "": { + "meanNs": 0.0044, + "allocatedBytes": 0 + } + }, + "OperatorBenchmarks\u003CPreciseNumber\u003E.LengthTimesLength": { + "": { + "meanNs": 167.7351, + "allocatedBytes": 48 + } + }, + "OperatorBenchmarks\u003CSingle\u003E.LengthTimesLength": { + "": { + "meanNs": 0.5166, + "allocatedBytes": 0 + } + }, + "UnitConversionBenchmarks\u003CDecimal\u003E.InNauticalMile": { + "": { + "meanNs": 73.2662, + "allocatedBytes": 0 + } + }, + "UnitConversionBenchmarks\u003CDouble\u003E.InNauticalMile": { + "": { + "meanNs": 6.7707, + "allocatedBytes": 0 + } + }, + "UnitConversionBenchmarks\u003CPreciseNumber\u003E.InNauticalMile": { + "": { + "meanNs": 986.6059, + "allocatedBytes": 232 + } + }, + "UnitConversionBenchmarks\u003CSingle\u003E.InNauticalMile": { + "": { + "meanNs": 7.0707, + "allocatedBytes": 0 + } + }, + "VectorBenchmarks\u003CDecimal\u003E.Length": { + "": { + "meanNs": 162.5991, + "allocatedBytes": 0 + } + }, + "VectorBenchmarks\u003CDouble\u003E.Length": { + "": { + "meanNs": 0.386, + "allocatedBytes": 0 + } + }, + "VectorBenchmarks\u003CPreciseNumber\u003E.Length": { + "": { + "meanNs": 1812.5825, + "allocatedBytes": 312 + } + }, + "VectorBenchmarks\u003CSingle\u003E.Length": { + "": { + "meanNs": 0.7382, + "allocatedBytes": 0 + } + } + } + }, + { + "version": "5.0.0", + "commit": "bb69de0", + "date": "2026-09-12", + "cpu": "Intel Xeon Processor 2.80GHz", + "runtime": ".NET 10.0.12 (10.0.12, 10.0.1226.42308)", + "baselineNs": 453.7426, + "runId": "local-seed", + "benchmarks": { + "AbstractionCostBenchmarks\u003CDecimal\u003E.BareAdd": { + "": { + "meanNs": 9.0051, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDecimal\u003E.BareMultiply": { + "": { + "meanNs": 81.7243, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDecimal\u003E.QuantityAdd": { + "": { + "meanNs": 9.3653, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDecimal\u003E.QuantityMultiply": { + "": { + "meanNs": 74.0881, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.BareAdd": { + "": { + "meanNs": 0.9876, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.BareMultiply": { + "": { + "meanNs": 1.3699, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.QuantityAdd": { + "": { + "meanNs": 0.9951, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.QuantityMultiply": { + "": { + "meanNs": 1.2741, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.BareAdd": { + "": { + "meanNs": 99.4237, + "allocatedBytes": 64 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.BareMultiply": { + "": { + "meanNs": 471.3418, + "allocatedBytes": 193 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.QuantityAdd": { + "": { + "meanNs": 99.6223, + "allocatedBytes": 64 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.QuantityMultiply": { + "": { + "meanNs": 480.1541, + "allocatedBytes": 193 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.BareAdd": { + "": { + "meanNs": 0.9839, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.BareMultiply": { + "": { + "meanNs": 1.3656, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.QuantityAdd": { + "": { + "meanNs": 0.9867, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.QuantityMultiply": { + "": { + "meanNs": 1.2713, + "allocatedBytes": 0 + } + }, + "ComparisonBenchmarks\u003CDecimal\u003E.CompareToInterface": { + "": { + "meanNs": 19.0738, + "allocatedBytes": 32 + } + }, + "ComparisonBenchmarks\u003CDouble\u003E.CompareToInterface": { + "": { + "meanNs": 14.8661, + "allocatedBytes": 24 + } + }, + "ComparisonBenchmarks\u003CPreciseNumber\u003E.CompareToInterface": { + "": { + "meanNs": 29.2044, + "allocatedBytes": 40 + } + }, + "ComparisonBenchmarks\u003CSingle\u003E.CompareToInterface": { + "": { + "meanNs": 13.5723, + "allocatedBytes": 24 + } + }, + "ConstructionBenchmarks\u003CDecimal\u003E.FromNauticalMile": { + "": { + "meanNs": 9.2106, + "allocatedBytes": 0 + } + }, + "ConstructionBenchmarks\u003CDouble\u003E.FromNauticalMile": { + "": { + "meanNs": 2.1179, + "allocatedBytes": 0 + } + }, + "ConstructionBenchmarks\u003CPreciseNumber\u003E.FromNauticalMile": { + "": { + "meanNs": 443.9862, + "allocatedBytes": 40 + } + }, + "ConstructionBenchmarks\u003CSingle\u003E.FromNauticalMile": { + "": { + "meanNs": 0.9297, + "allocatedBytes": 0 + } + }, + "OperatorBenchmarks\u003CDecimal\u003E.LengthTimesLength": { + "": { + "meanNs": 49.1925, + "allocatedBytes": 0 + } + }, + "OperatorBenchmarks\u003CDouble\u003E.LengthTimesLength": { + "": { + "meanNs": 0, + "allocatedBytes": 0 + } + }, + "OperatorBenchmarks\u003CPreciseNumber\u003E.LengthTimesLength": { + "": { + "meanNs": 169.9505, + "allocatedBytes": 48 + } + }, + "OperatorBenchmarks\u003CSingle\u003E.LengthTimesLength": { + "": { + "meanNs": 0.0022, + "allocatedBytes": 0 + } + }, + "UnitConversionBenchmarks\u003CDecimal\u003E.InNauticalMile": { + "": { + "meanNs": 70.5056, + "allocatedBytes": 0 + } + }, + "UnitConversionBenchmarks\u003CDouble\u003E.InNauticalMile": { + "": { + "meanNs": 6.8206, + "allocatedBytes": 0 + } + }, + "UnitConversionBenchmarks\u003CPreciseNumber\u003E.InNauticalMile": { + "": { + "meanNs": 983.3212, + "allocatedBytes": 232 + } + }, + "UnitConversionBenchmarks\u003CSingle\u003E.InNauticalMile": { + "": { + "meanNs": 7.3736, + "allocatedBytes": 0 + } + }, + "VectorBenchmarks\u003CDecimal\u003E.Length": { + "": { + "meanNs": 162.6187, + "allocatedBytes": 0 + } + }, + "VectorBenchmarks\u003CDouble\u003E.Length": { + "": { + "meanNs": 0.3811, + "allocatedBytes": 0 + } + }, + "VectorBenchmarks\u003CPreciseNumber\u003E.Length": { + "": { + "meanNs": 1830.3698, + "allocatedBytes": 312 + } + }, + "VectorBenchmarks\u003CSingle\u003E.Length": { + "": { + "meanNs": 0.7777, + "allocatedBytes": 0 + } + } + } + }, + { + "version": "5.1.0", + "commit": "4c71e14", + "date": "2026-09-13", + "cpu": "Intel Xeon Processor 2.80GHz", + "runtime": ".NET 10.0.12 (10.0.12, 10.0.1226.42308)", + "baselineNs": 453.7426, + "runId": "local-seed", + "benchmarks": { + "AbstractionCostBenchmarks\u003CDecimal\u003E.BareAdd": { + "": { + "meanNs": 8.5973, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDecimal\u003E.BareMultiply": { + "": { + "meanNs": 82.0963, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDecimal\u003E.QuantityAdd": { + "": { + "meanNs": 9.1455, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDecimal\u003E.QuantityMultiply": { + "": { + "meanNs": 71.7464, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.BareAdd": { + "": { + "meanNs": 0.9877, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.BareMultiply": { + "": { + "meanNs": 1.3571, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.QuantityAdd": { + "": { + "meanNs": 0.9909, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.QuantityMultiply": { + "": { + "meanNs": 1.273, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.BareAdd": { + "": { + "meanNs": 97.5927, + "allocatedBytes": 64 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.BareMultiply": { + "": { + "meanNs": 469.9466, + "allocatedBytes": 193 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.QuantityAdd": { + "": { + "meanNs": 97.6082, + "allocatedBytes": 64 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.QuantityMultiply": { + "": { + "meanNs": 493.8879, + "allocatedBytes": 193 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.BareAdd": { + "": { + "meanNs": 0.9983, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.BareMultiply": { + "": { + "meanNs": 1.3533, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.QuantityAdd": { + "": { + "meanNs": 0.9883, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.QuantityMultiply": { + "": { + "meanNs": 1.2692, + "allocatedBytes": 0 + } + }, + "ComparisonBenchmarks\u003CDecimal\u003E.CompareToInterface": { + "": { + "meanNs": 18.7677, + "allocatedBytes": 32 + } + }, + "ComparisonBenchmarks\u003CDouble\u003E.CompareToInterface": { + "": { + "meanNs": 14.2, + "allocatedBytes": 24 + } + }, + "ComparisonBenchmarks\u003CPreciseNumber\u003E.CompareToInterface": { + "": { + "meanNs": 33.6128, + "allocatedBytes": 40 + } + }, + "ComparisonBenchmarks\u003CSingle\u003E.CompareToInterface": { + "": { + "meanNs": 14.8604, + "allocatedBytes": 24 + } + }, + "ConstructionBenchmarks\u003CDecimal\u003E.FromNauticalMile": { + "": { + "meanNs": 9.1531, + "allocatedBytes": 0 + } + }, + "ConstructionBenchmarks\u003CDouble\u003E.FromNauticalMile": { + "": { + "meanNs": 2.0603, + "allocatedBytes": 0 + } + }, + "ConstructionBenchmarks\u003CPreciseNumber\u003E.FromNauticalMile": { + "": { + "meanNs": 452.3783, + "allocatedBytes": 40 + } + }, + "ConstructionBenchmarks\u003CSingle\u003E.FromNauticalMile": { + "": { + "meanNs": 0.9557, + "allocatedBytes": 0 + } + }, + "OperatorBenchmarks\u003CDecimal\u003E.LengthTimesLength": { + "": { + "meanNs": 49.0283, + "allocatedBytes": 0 + } + }, + "OperatorBenchmarks\u003CDouble\u003E.LengthTimesLength": { + "": { + "meanNs": 0.5081, + "allocatedBytes": 0 + } + }, + "OperatorBenchmarks\u003CPreciseNumber\u003E.LengthTimesLength": { + "": { + "meanNs": 176.6406, + "allocatedBytes": 48 + } + }, + "OperatorBenchmarks\u003CSingle\u003E.LengthTimesLength": { + "": { + "meanNs": 0.0023, + "allocatedBytes": 0 + } + }, + "UnitConversionBenchmarks\u003CDecimal\u003E.InNauticalMile": { + "": { + "meanNs": 70.6187, + "allocatedBytes": 0 + } + }, + "UnitConversionBenchmarks\u003CDouble\u003E.InNauticalMile": { + "": { + "meanNs": 7.0158, + "allocatedBytes": 0 + } + }, + "UnitConversionBenchmarks\u003CPreciseNumber\u003E.InNauticalMile": { + "": { + "meanNs": 1006.533, + "allocatedBytes": 232 + } + }, + "UnitConversionBenchmarks\u003CSingle\u003E.InNauticalMile": { + "": { + "meanNs": 7.287, + "allocatedBytes": 0 + } + }, + "VectorBenchmarks\u003CDecimal\u003E.Length": { + "": { + "meanNs": 161.1028, + "allocatedBytes": 0 + } + }, + "VectorBenchmarks\u003CDouble\u003E.Length": { + "": { + "meanNs": 0.3802, + "allocatedBytes": 0 + } + }, + "VectorBenchmarks\u003CPreciseNumber\u003E.Length": { + "": { + "meanNs": 1759.7936, + "allocatedBytes": 312 + } + }, + "VectorBenchmarks\u003CSingle\u003E.Length": { + "": { + "meanNs": 0.7501, + "allocatedBytes": 0 + } + } + } + }, + { + "version": "5.2.0", + "commit": "eda9fc8", + "date": "2026-09-13", + "cpu": "Intel Xeon Processor 2.80GHz", + "runtime": ".NET 10.0.12 (10.0.12, 10.0.1226.42308)", + "baselineNs": 453.7426, + "runId": "local-seed", + "benchmarks": { + "AbstractionCostBenchmarks\u003CDecimal\u003E.BareAdd": { + "": { + "meanNs": 8.6999, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDecimal\u003E.BareMultiply": { + "": { + "meanNs": 83.8402, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDecimal\u003E.QuantityAdd": { + "": { + "meanNs": 9.1445, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDecimal\u003E.QuantityMultiply": { + "": { + "meanNs": 71.8414, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.BareAdd": { + "": { + "meanNs": 0.9906, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.BareMultiply": { + "": { + "meanNs": 1.3557, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.QuantityAdd": { + "": { + "meanNs": 0.9959, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.QuantityMultiply": { + "": { + "meanNs": 1.2703, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.BareAdd": { + "": { + "meanNs": 98.1186, + "allocatedBytes": 64 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.BareMultiply": { + "": { + "meanNs": 482.7433, + "allocatedBytes": 193 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.QuantityAdd": { + "": { + "meanNs": 99.6921, + "allocatedBytes": 64 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.QuantityMultiply": { + "": { + "meanNs": 491.7768, + "allocatedBytes": 193 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.BareAdd": { + "": { + "meanNs": 0.996, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.BareMultiply": { + "": { + "meanNs": 1.3552, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.QuantityAdd": { + "": { + "meanNs": 1.0292, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.QuantityMultiply": { + "": { + "meanNs": 1.2945, + "allocatedBytes": 0 + } + }, + "ComparisonBenchmarks\u003CDecimal\u003E.CompareToInterface": { + "": { + "meanNs": 19.0692, + "allocatedBytes": 32 + } + }, + "ComparisonBenchmarks\u003CDouble\u003E.CompareToInterface": { + "": { + "meanNs": 14.8967, + "allocatedBytes": 24 + } + }, + "ComparisonBenchmarks\u003CPreciseNumber\u003E.CompareToInterface": { + "": { + "meanNs": 30.4616, + "allocatedBytes": 40 + } + }, + "ComparisonBenchmarks\u003CSingle\u003E.CompareToInterface": { + "": { + "meanNs": 13.6837, + "allocatedBytes": 24 + } + }, + "ConstructionBenchmarks\u003CDecimal\u003E.FromNauticalMile": { + "": { + "meanNs": 7.9634, + "allocatedBytes": 0 + } + }, + "ConstructionBenchmarks\u003CDouble\u003E.FromNauticalMile": { + "": { + "meanNs": 2.0738, + "allocatedBytes": 0 + } + }, + "ConstructionBenchmarks\u003CPreciseNumber\u003E.FromNauticalMile": { + "": { + "meanNs": 105.7268, + "allocatedBytes": 40 + } + }, + "ConstructionBenchmarks\u003CSingle\u003E.FromNauticalMile": { + "": { + "meanNs": 0.9101, + "allocatedBytes": 0 + } + }, + "OperatorBenchmarks\u003CDecimal\u003E.LengthTimesLength": { + "": { + "meanNs": 51.1049, + "allocatedBytes": 0 + } + }, + "OperatorBenchmarks\u003CDouble\u003E.LengthTimesLength": { + "": { + "meanNs": 0.5461, + "allocatedBytes": 0 + } + }, + "OperatorBenchmarks\u003CPreciseNumber\u003E.LengthTimesLength": { + "": { + "meanNs": 169.9915, + "allocatedBytes": 48 + } + }, + "OperatorBenchmarks\u003CSingle\u003E.LengthTimesLength": { + "": { + "meanNs": 0.0143, + "allocatedBytes": 0 + } + }, + "UnitConversionBenchmarks\u003CDecimal\u003E.InNauticalMile": { + "": { + "meanNs": 80.3569, + "allocatedBytes": 0 + } + }, + "UnitConversionBenchmarks\u003CDouble\u003E.InNauticalMile": { + "": { + "meanNs": 17.4057, + "allocatedBytes": 0 + } + }, + "UnitConversionBenchmarks\u003CPreciseNumber\u003E.InNauticalMile": { + "": { + "meanNs": 658.122, + "allocatedBytes": 232 + } + }, + "UnitConversionBenchmarks\u003CSingle\u003E.InNauticalMile": { + "": { + "meanNs": 21.0595, + "allocatedBytes": 0 + } + }, + "VectorBenchmarks\u003CDecimal\u003E.Length": { + "": { + "meanNs": 511.343, + "allocatedBytes": 0 + } + }, + "VectorBenchmarks\u003CDouble\u003E.Length": { + "": { + "meanNs": 1.0068, + "allocatedBytes": 0 + } + }, + "VectorBenchmarks\u003CPreciseNumber\u003E.Length": { + "": { + "meanNs": 6467.5104, + "allocatedBytes": 1760 + } + }, + "VectorBenchmarks\u003CSingle\u003E.Length": { + "": { + "meanNs": 1.0074, + "allocatedBytes": 0 + } + } + } + }, + { + "version": "5.2.4", + "commit": "cbc914c", + "date": "2026-09-14", + "cpu": "Intel Xeon Processor 2.80GHz", + "runtime": ".NET 10.0.12 (10.0.12, 10.0.1226.42308)", + "baselineNs": 453.7426, + "runId": "local-seed", + "benchmarks": { + "AbstractionCostBenchmarks\u003CDecimal\u003E.BareAdd": { + "": { + "meanNs": 8.5802, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDecimal\u003E.BareMultiply": { + "": { + "meanNs": 82.3614, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDecimal\u003E.QuantityAdd": { + "": { + "meanNs": 8.9643, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDecimal\u003E.QuantityMultiply": { + "": { + "meanNs": 72.0014, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.BareAdd": { + "": { + "meanNs": 0.9861, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.BareMultiply": { + "": { + "meanNs": 1.3742, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.QuantityAdd": { + "": { + "meanNs": 0.984, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.QuantityMultiply": { + "": { + "meanNs": 1.2717, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.BareAdd": { + "": { + "meanNs": 96.1031, + "allocatedBytes": 64 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.BareMultiply": { + "": { + "meanNs": 499.0323, + "allocatedBytes": 193 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.QuantityAdd": { + "": { + "meanNs": 98.6081, + "allocatedBytes": 64 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.QuantityMultiply": { + "": { + "meanNs": 489.1922, + "allocatedBytes": 193 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.BareAdd": { + "": { + "meanNs": 0.9829, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.BareMultiply": { + "": { + "meanNs": 1.3593, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.QuantityAdd": { + "": { + "meanNs": 0.9946, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.QuantityMultiply": { + "": { + "meanNs": 1.2711, + "allocatedBytes": 0 + } + }, + "ComparisonBenchmarks\u003CDecimal\u003E.CompareToInterface": { + "": { + "meanNs": 18.8546, + "allocatedBytes": 32 + } + }, + "ComparisonBenchmarks\u003CDouble\u003E.CompareToInterface": { + "": { + "meanNs": 13.4705, + "allocatedBytes": 24 + } + }, + "ComparisonBenchmarks\u003CPreciseNumber\u003E.CompareToInterface": { + "": { + "meanNs": 28.5842, + "allocatedBytes": 40 + } + }, + "ComparisonBenchmarks\u003CSingle\u003E.CompareToInterface": { + "": { + "meanNs": 13.3108, + "allocatedBytes": 24 + } + }, + "ConstructionBenchmarks\u003CDecimal\u003E.FromNauticalMile": { + "": { + "meanNs": 16.0457, + "allocatedBytes": 0 + } + }, + "ConstructionBenchmarks\u003CDouble\u003E.FromNauticalMile": { + "": { + "meanNs": 3.7591, + "allocatedBytes": 0 + } + }, + "ConstructionBenchmarks\u003CPreciseNumber\u003E.FromNauticalMile": { + "": { + "meanNs": 118.9315, + "allocatedBytes": 40 + } + }, + "ConstructionBenchmarks\u003CSingle\u003E.FromNauticalMile": { + "": { + "meanNs": 2.0821, + "allocatedBytes": 0 + } + }, + "OperatorBenchmarks\u003CDecimal\u003E.LengthTimesLength": { + "": { + "meanNs": 49.5242, + "allocatedBytes": 0 + } + }, + "OperatorBenchmarks\u003CDouble\u003E.LengthTimesLength": { + "": { + "meanNs": 0.0007, + "allocatedBytes": 0 + } + }, + "OperatorBenchmarks\u003CPreciseNumber\u003E.LengthTimesLength": { + "": { + "meanNs": 171.823, + "allocatedBytes": 48 + } + }, + "OperatorBenchmarks\u003CSingle\u003E.LengthTimesLength": { + "": { + "meanNs": 0.5446, + "allocatedBytes": 0 + } + }, + "UnitConversionBenchmarks\u003CDecimal\u003E.InNauticalMile": { + "": { + "meanNs": 81.1356, + "allocatedBytes": 0 + } + }, + "UnitConversionBenchmarks\u003CDouble\u003E.InNauticalMile": { + "": { + "meanNs": 18.9727, + "allocatedBytes": 0 + } + }, + "UnitConversionBenchmarks\u003CPreciseNumber\u003E.InNauticalMile": { + "": { + "meanNs": 643.2338, + "allocatedBytes": 232 + } + }, + "UnitConversionBenchmarks\u003CSingle\u003E.InNauticalMile": { + "": { + "meanNs": 19.613, + "allocatedBytes": 0 + } + }, + "VectorBenchmarks\u003CDecimal\u003E.Length": { + "": { + "meanNs": 523.8651, + "allocatedBytes": 0 + } + }, + "VectorBenchmarks\u003CDouble\u003E.Length": { + "": { + "meanNs": 1.0053, + "allocatedBytes": 0 + } + }, + "VectorBenchmarks\u003CPreciseNumber\u003E.Length": { + "": { + "meanNs": 6455.894, + "allocatedBytes": 1760 + } + }, + "VectorBenchmarks\u003CSingle\u003E.Length": { + "": { + "meanNs": 0.972, + "allocatedBytes": 0 + } + } + } + }, + { + "version": "5.3.2", + "commit": "2a3e53b", + "date": "2026-09-16", + "cpu": "Intel Xeon Processor 2.80GHz", + "runtime": ".NET 10.0.12 (10.0.12, 10.0.1226.42308)", + "baselineNs": 453.7426, + "runId": "local-seed", + "benchmarks": { + "AbstractionCostBenchmarks\u003CDecimal\u003E.BareAdd": { + "": { + "meanNs": 8.6763, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDecimal\u003E.BareMultiply": { + "": { + "meanNs": 82.6289, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDecimal\u003E.QuantityAdd": { + "": { + "meanNs": 8.9875, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDecimal\u003E.QuantityMultiply": { + "": { + "meanNs": 70.95, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.BareAdd": { + "": { + "meanNs": 0.9939, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.BareMultiply": { + "": { + "meanNs": 1.3535, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.QuantityAdd": { + "": { + "meanNs": 0.9884, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CDouble\u003E.QuantityMultiply": { + "": { + "meanNs": 1.2791, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.BareAdd": { + "": { + "meanNs": 97.9298, + "allocatedBytes": 64 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.BareMultiply": { + "": { + "meanNs": 470.9339, + "allocatedBytes": 193 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.QuantityAdd": { + "": { + "meanNs": 98.1314, + "allocatedBytes": 64 + } + }, + "AbstractionCostBenchmarks\u003CPreciseNumber\u003E.QuantityMultiply": { + "": { + "meanNs": 485.8132, + "allocatedBytes": 193 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.BareAdd": { + "": { + "meanNs": 0.992, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.BareMultiply": { + "": { + "meanNs": 1.3621, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.QuantityAdd": { + "": { + "meanNs": 0.9919, + "allocatedBytes": 0 + } + }, + "AbstractionCostBenchmarks\u003CSingle\u003E.QuantityMultiply": { + "": { + "meanNs": 1.2794, + "allocatedBytes": 0 + } + }, + "ComparisonBenchmarks\u003CDecimal\u003E.CompareToInterface": { + "": { + "meanNs": 18.179, + "allocatedBytes": 32 + } + }, + "ComparisonBenchmarks\u003CDouble\u003E.CompareToInterface": { + "": { + "meanNs": 13.9138, + "allocatedBytes": 24 + } + }, + "ComparisonBenchmarks\u003CPreciseNumber\u003E.CompareToInterface": { + "": { + "meanNs": 28.6637, + "allocatedBytes": 40 + } + }, + "ComparisonBenchmarks\u003CSingle\u003E.CompareToInterface": { + "": { + "meanNs": 12.9947, + "allocatedBytes": 24 + } + }, + "ConstructionBenchmarks\u003CDecimal\u003E.FromNauticalMile": { + "": { + "meanNs": 15.3997, + "allocatedBytes": 0 + } + }, + "ConstructionBenchmarks\u003CDouble\u003E.FromNauticalMile": { + "": { + "meanNs": 3.2909, + "allocatedBytes": 0 + } + }, + "ConstructionBenchmarks\u003CPreciseNumber\u003E.FromNauticalMile": { + "": { + "meanNs": 119.6148, + "allocatedBytes": 40 + } + }, + "ConstructionBenchmarks\u003CSingle\u003E.FromNauticalMile": { + "": { + "meanNs": 2.0393, + "allocatedBytes": 0 + } + }, + "OperatorBenchmarks\u003CDecimal\u003E.LengthTimesLength": { + "": { + "meanNs": 49.2968, + "allocatedBytes": 0 + } + }, + "OperatorBenchmarks\u003CDouble\u003E.LengthTimesLength": { + "": { + "meanNs": 0, + "allocatedBytes": 0 + } + }, + "OperatorBenchmarks\u003CPreciseNumber\u003E.LengthTimesLength": { + "": { + "meanNs": 171.2329, + "allocatedBytes": 48 + } + }, + "OperatorBenchmarks\u003CSingle\u003E.LengthTimesLength": { + "": { + "meanNs": 0.0246, + "allocatedBytes": 0 + } + }, + "UnitConversionBenchmarks\u003CDecimal\u003E.InNauticalMile": { + "": { + "meanNs": 82.4458, + "allocatedBytes": 0 + } + }, + "UnitConversionBenchmarks\u003CDouble\u003E.InNauticalMile": { + "": { + "meanNs": 19.7129, + "allocatedBytes": 0 + } + }, + "UnitConversionBenchmarks\u003CPreciseNumber\u003E.InNauticalMile": { + "": { + "meanNs": 639.269, + "allocatedBytes": 232 + } + }, + "UnitConversionBenchmarks\u003CSingle\u003E.InNauticalMile": { + "": { + "meanNs": 23.0065, + "allocatedBytes": 0 + } + }, + "VectorBenchmarks\u003CDecimal\u003E.Length": { + "": { + "meanNs": 526.858, + "allocatedBytes": 0 + } + }, + "VectorBenchmarks\u003CDouble\u003E.Length": { + "": { + "meanNs": 0.9356, + "allocatedBytes": 0 + } + }, + "VectorBenchmarks\u003CPreciseNumber\u003E.Length": { + "": { + "meanNs": 6434.8509, + "allocatedBytes": 1760 + } + }, + "VectorBenchmarks\u003CSingle\u003E.Length": { + "": { + "meanNs": 0.9459, + "allocatedBytes": 0 + } + } + } } ] } diff --git a/docs/benchmarks/performance-dark.svg b/docs/benchmarks/performance-dark.svg index 406755d..eb02234 100644 --- a/docs/benchmarks/performance-dark.svg +++ b/docs/benchmarks/performance-dark.svg @@ -1,4 +1,4 @@ - + - + Semantics.Quantities performance by release 10 releases · newest 5.3.2 · 2026-09-16 @@ -140,124 +140,187 @@ Divided by a reference loop measured in the same job, which cancels most of the difference between CI runners. Lower is faster. Construct (double) - + - - - - - - - - - -0.0074× -0.0602× + + + + + + + + + +0.0073× +0.0676× Construct (float) - + - - - - - - + + + + + + - -0.0044× -0.0624× + +0.0045× +0.0647× Construct (decimal) - + - - - - - - - - - -0.0342× -0.0955× + + + + + + + + + +0.0339× +0.103× Construct (precise) - + - - - - - - - - - -0.262× -1.14× + + + + + + + + + +0.264× +1.13× Read back (decimal) - - - - - + + + + + - - - - + + + + 0.182× -0.157× +0.156× Read back (precise) - - - - - - - - - - - -1.39× -2.18× + + + + + + + + + + + +1.41× +2.20× Vector length (decimal) - - - - - - - - - - - -1.13× -0.359× + + + + + + + + + + + +1.16× +0.359× CompareTo (double) - - - - - - - - - - - -0.0289× -0.0105× -releases, oldest to newest: 3.3.1 → 4.0.0 → 4.1.0 → 4.2.0 → 4.3.2 → 5.0.0 → 5.1.0 → 5.2.0 → 5.2.4 → 5.3.2 -Measured on Intel Xeon Processor 2.80GHz. Full tables: Semantics.Benchmarks. + + + + + + + + + + + +0.0307× +0.0098× + +Cost of the quantity wrapper over the bare storage type +Divided by the identical loop on the bare storage type, measured beside it. A quantity holds one value and adds no work of its own, so this belongs at 1. +Add (double) + + + + + + + + + + + + +0.994× +27.8× +Multiply (double) + + + + + + + + + + + + +0.945× +56.4× +Multiply (decimal) + + + + + + + + + + + + +0.859× +2.27× +Multiply (precise) + + + + + + + + + + + + +1.03× +1.33× +releases, oldest to newest: 3.3.1 → 4.0.0 → 4.1.0 → 4.2.0 → 4.3.2 → 5.0.0 → 5.1.0 → 5.2.0 → 5.2.4 → 5.3.2 +Measured on Intel Xeon Processor 2.80GHz. Full tables: Semantics.Benchmarks. diff --git a/docs/benchmarks/performance.svg b/docs/benchmarks/performance.svg index 90a9ea9..33378a3 100644 --- a/docs/benchmarks/performance.svg +++ b/docs/benchmarks/performance.svg @@ -1,4 +1,4 @@ - + - + Semantics.Quantities performance by release 10 releases · newest 5.3.2 · 2026-09-16 @@ -140,124 +140,187 @@ Divided by a reference loop measured in the same job, which cancels most of the difference between CI runners. Lower is faster. Construct (double) - + - - - - - - - - - -0.0074× -0.0602× + + + + + + + + + +0.0073× +0.0676× Construct (float) - + - - - - - - + + + + + + - -0.0044× -0.0624× + +0.0045× +0.0647× Construct (decimal) - + - - - - - - - - - -0.0342× -0.0955× + + + + + + + + + +0.0339× +0.103× Construct (precise) - + - - - - - - - - - -0.262× -1.14× + + + + + + + + + +0.264× +1.13× Read back (decimal) - - - - - + + + + + - - - - + + + + 0.182× -0.157× +0.156× Read back (precise) - - - - - - - - - - - -1.39× -2.18× + + + + + + + + + + + +1.41× +2.20× Vector length (decimal) - - - - - - - - - - - -1.13× -0.359× + + + + + + + + + + + +1.16× +0.359× CompareTo (double) - - - - - - - - - - - -0.0289× -0.0105× -releases, oldest to newest: 3.3.1 → 4.0.0 → 4.1.0 → 4.2.0 → 4.3.2 → 5.0.0 → 5.1.0 → 5.2.0 → 5.2.4 → 5.3.2 -Measured on Intel Xeon Processor 2.80GHz. Full tables: Semantics.Benchmarks. + + + + + + + + + + + +0.0307× +0.0098× + +Cost of the quantity wrapper over the bare storage type +Divided by the identical loop on the bare storage type, measured beside it. A quantity holds one value and adds no work of its own, so this belongs at 1. +Add (double) + + + + + + + + + + + + +0.994× +27.8× +Multiply (double) + + + + + + + + + + + + +0.945× +56.4× +Multiply (decimal) + + + + + + + + + + + + +0.859× +2.27× +Multiply (precise) + + + + + + + + + + + + +1.03× +1.33× +releases, oldest to newest: 3.3.1 → 4.0.0 → 4.1.0 → 4.2.0 → 4.3.2 → 5.0.0 → 5.1.0 → 5.2.0 → 5.2.4 → 5.3.2 +Measured on Intel Xeon Processor 2.80GHz. Full tables: Semantics.Benchmarks.