BENCHMARKS · NUMERICS & SIMD

Vectorized math: scalar loops vs hand-rolled SIMD vs TensorPrimitives. Suite and raw reports: github.com/gdhami-net/dotnet-benchmarks.

Intel Core Ultra 9 285HX · Windows 11 · BenchmarkDotNet 0.15.8 · SDK 10.0.201 · 2026-08-22 · single run — not yet median-of-N · bars/tables: mean time, lower is better

SumFloats

Sum 100,000 floats: scalar loop vs hand-rolled Vector<T> SIMD vs TensorPrimitives.

TAKEAWAY Reach for TensorPrimitives first: it's the SIMD win without writing SIMD, and it keeps improving with each release. Hand-rolled Vector<T> only earns its complexity when you need an operation TensorPrimitives doesn't ship.
In this run: TensorPrimitives_sum is fastest — 8.1× faster than the baseline.
RESULTS
methodnet9.0net10.0ratioallocatedΔ net10.0
Scalar_loop baseline38.0 µs ±622 ns38.3 µs ±545 ns1.00×+1%
Vector_simd4.9 µs ±64 ns4.8 µs ±10 ns0.13×-2%
TensorPrimitives_sum4.8 µs ±9 ns4.7 µs ±62 ns0.12×-2%
RATIO VS BASELINE · net10.0
Scalar_loop
1.00×
Vector_simd
0.13×
TensorPrimitives_sum
0.12×
THE LEDGER · SAME WORKLOAD ACROSS RELEASES (LOG)

The ledger starts here — 3 run recorded. Trend lines appear from the second release onward.

THE CODE BEING MEASURED
Scalar_loop — what this measures

Plain scalar loop — one float at a time.

[Benchmark (Baseline)]
public float Scalar_loop()
{
    var sum = 0f;
    foreach (var v in _values) sum += v;
    return sum;
}
Vector_simd — what this measures

Hand-written Vector<float> SIMD with a scalar tail.

[Benchmark]
public float Vector_simd()
{
    var acc = Vector<float>.Zero;
    var span = _values.AsSpan();
    var i = 0;
    for (; i <= span.Length - Vector<float>.Count; i += Vector<float>.Count)
        acc += new Vector<float>(span.Slice(i, Vector<float>.Count));
    var sum = Vector.Sum(acc);
    for (; i < span.Length; i++) sum += span[i];
    return sum;
}
TensorPrimitives_sum — what this measures

TensorPrimitives.Sum — the BCL's vectorized kernel.

[Benchmark]
public float TensorPrimitives_sum()
=> TensorPrimitives.Sum(_values);

DotProduct

Dot product of two 100,000-float vectors: scalar vs TensorPrimitives.

TAKEAWAY If you're writing embeddings/similarity code by hand, stop: TensorPrimitives.Dot is the one-liner that's also the fast path.
In this run: TensorPrimitives_dot is fastest — 6.8× faster than the baseline.
RESULTS
methodnet9.0net10.0ratioallocatedΔ net10.0
Scalar_dot baseline41.3 µs ±75 ns42.4 µs ±1.0 µs1.00×+3%
TensorPrimitives_dot6.2 µs ±111 ns6.2 µs ±60 ns0.15×-0%
RATIO VS BASELINE · net10.0
Scalar_dot
1.00×
TensorPrimitives_dot
0.15×
THE LEDGER · SAME WORKLOAD ACROSS RELEASES (LOG)

The ledger starts here — 3 run recorded. Trend lines appear from the second release onward.

THE CODE BEING MEASURED
Scalar_dot — what this measures

Scalar multiply-accumulate loop.

[Benchmark (Baseline)]
public float Scalar_dot()
{
    var sum = 0f;
    for (var i = 0; i < _a.Length; i++) sum += _a[i] * _b[i];
    return sum;
}
TensorPrimitives_dot — what this measures

TensorPrimitives.Dot.

[Benchmark]
public float TensorPrimitives_dot()
=> TensorPrimitives.Dot(_a, _b);