Skip to content

Expand SKMatrix tracking benchmarks for the managed-port surface (#4241) - #4480

Merged
mattleibow merged 1 commit into
mainfrom
dev/expand-matrix-benchmarks
Jul 17, 2026
Merged

Expand SKMatrix tracking benchmarks for the managed-port surface (#4241)#4480
mattleibow merged 1 commit into
mainfrom
dev/expand-matrix-benchmarks

Conversation

@mattleibow

Copy link
Copy Markdown
Contributor

What

Broaden SkiaSharp.Benchmarks.Tracking coverage of the SKMatrix surface that #4241 (port SKMatrix math to managed C#) improves. Today the only SKMatrix tracker is MatrixMapPointsBenchmark.MapPoints — the batch overload, which is the weakest indicator of #4241: the batch does a single native call for the whole array, so the per-call P/Invoke #4241 removes is amortised away. The single-op operations, where the managed↔native transition is paid every call, are where the win shows — and they had no permanent coverage.

Split the surface into two tracked groups, mirroring how #4241 changes it:

  • MatrixMapPointsBenchmark (expanded — geometry mapping): add MapPoint, MapRect, MapVector, MapRadius, each looped over the existing deterministic point set. The pre-existing MapPoints method and its Points params are left untouched (a shipped history key must never be renamed). New methods are allocation-free; MapPoints keeps its allocating batch behaviour as a signal.
  • MatrixOpsBenchmark (new — matrix algebra): Concat (pre + post multiply) and Invert — the ops that produce another matrix rather than mapping geometry.

Not added: MapVectors/MapPoints-batch duplicates (the existing batch MapPoints already represents that case) and the perspective path (#4241 falls back to native there — no gain to track).

Why these will move (and the batch barely will)

Local --job short vs the 4.151 nightly, per 4096-element workload — all zero-alloc:

Benchmark Mean (4096) Note
MatrixMapPointsBenchmark.MapPoints (batch) 1.88 µs one native call — P/Invoke amortised, barely moves under #4241
MatrixMapPointsBenchmark.MapPoint 24.6 µs ~13× costlier/point than the batch = the P/Invoke #4241 removes
MatrixMapPointsBenchmark.MapRect 55.3 µs
MatrixMapPointsBenchmark.MapVector 57.8 µs
MatrixMapPointsBenchmark.MapRadius 118 µs 2 vectors/call
MatrixOpsBenchmark.Concat 125 µs pre + post multiply
MatrixOpsBenchmark.Invert 71.5 µs

Since these paths are already zero-alloc, #4241's signal is a time drop; allocations stay flat at 0.

Constraints honoured

  • Public API only (nightly NuGet ref); deterministic (fixed seed, no fonts/content).
  • Affine operands (rotation/scale/translate) → Port SKMatrix math to managed C# to remove native interop (#2779) #4241's managed fast path.
  • MatrixMapPointsBenchmark/MapPoints/Points unchanged (never-rename rule).
  • Verified to compile against both the 3.119.4 baseline and 4.151 nightly — no new #if.

Follow-up: once this lands, update-branch #4241 so its pr column is measured against this expanded coverage.

The tracking suite only measured SKMatrix.MapPoints (the batch overload), which
is the weakest indicator of the managed SKMatrix port in #4241: the batch does a
single native call for the whole array, so the per-call P/Invoke that #4241
removes is amortised to almost nothing. The single-op operations - where the
managed<->native transition is paid on every call - are where that win actually
shows, and they had no permanent coverage.

Split the SKMatrix surface into two tracked groups, mirroring how #4241 changes it:

  * MatrixMapPointsBenchmark (expanded, geometry mapping) - add MapPoint, MapRect,
    MapVector and MapRadius, each looped over the existing deterministic point set.
    The pre-existing MapPoints method and its Points params are left untouched (a
    shipped history key must never be renamed). All the new methods are
    allocation-free; MapPoints keeps its allocating batch behaviour as a signal.
  * MatrixOpsBenchmark (new, matrix algebra) - Concat (pre + post multiply) and
    Invert, the operations that produce another matrix rather than mapping geometry.

Local short-run against the 4.151 nightly shows the single-op methods are dominated
by interop overhead (MapPoint 24.6 us vs the MapPoints batch 1.88 us for the same
4096 points; MapRect 55 us, MapRadius 118 us, Concat 125 us, Invert 71 us) - all
zero-alloc - so #4241 should visibly drop their time lines while the batch barely
moves. The operands are affine (rotation/scale/translate), which is #4241's managed
fast path; perspective would fall back to native. Public API only, deterministic
(fixed seed), and verified to compile against both the 3.119.4 baseline and 4.151
nightly (no new #if needed).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ca69afac-998b-493d-a03c-d9b25dd3f15b
@github-actions

Copy link
Copy Markdown
Contributor

📦 Try the packages from this PR

Warning

Do not run these scripts without first reviewing the code in this PR.

Step 1 — Download the packages

bash / macOS / Linux:

curl -fsSL https://raw.githubusercontent.com/mono/SkiaSharp/main/scripts/get-skiasharp-pr.sh | bash -s -- 4480

PowerShell / Windows:

iex "& { $(irm https://raw.githubusercontent.com/mono/SkiaSharp/main/scripts/get-skiasharp-pr.ps1) } 4480"

Step 2 — Add the local NuGet source

dotnet nuget add source ~/.skiasharp/hives/pr-4480/packages --name skiasharp-pr-4480
More options
Option Description
--successful-only / -SuccessfulOnly Only use successful builds
--force / -Force Overwrite previously downloaded packages
--list / -List List available artifacts without downloading
--build-id ID / -BuildId ID Download from a specific build

Or download manually from Azure Pipelines — look for the nuget artifact on the build for this PR.

Remove the source when you're done:

dotnet nuget remove source skiasharp-pr-4480

@mattleibow
mattleibow merged commit c439855 into main Jul 17, 2026
23 of 85 checks passed
@mattleibow
mattleibow deleted the dev/expand-matrix-benchmarks branch July 17, 2026 22:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant