Add regression-tracking benchmarks for common colour/interop paths#4476
Merged
Conversation
Expand SkiaSharp.Benchmarks.Tracking with a small, curated set of permanent regression benchmarks derived from recent perf/agentic PRs, following the project's scaled-pyramid philosophy (a few small common-path trackers + one large "touch many things" indicator, not per-PR micro sprawl). Tier 1 - small common-path trackers: - ColorMathBenchmark: managed SKColor->SKColorF (#4370) + SKPMColor PreMultiply/UnPreMultiply (#4385). Zero-alloc; the ToColorF/ToColor ratio (reverse stays native) is a managed-regression signal. - RasterImageLifecycleBenchmark: create+dispose churn of SKImage.Create raster (#4455) and SKData.Create with a managed release proc (#4453). Allocation is the tracked signal for the leak-fix area. - RuntimeEffectShaderBenchmark: per-frame animated SkSL shader - build uniforms (SKColor uniform hits #4370), ToShader, draw. Exercises the uniforms lifecycle whose SKData leak #4442 fixed. Tier 2 - large composite: - SceneRenderBenchmark: one broad frame (transforms, linear+radial gradients, filled/stroked primitives, a built path, a scaled image draw, a colour-filter layer, clipping, managed colour maths) so many future optimizations each nudge it - a merge indicator. All are public-API only, deterministic (fixed seeds, no fonts/external content), and compile against both the 3.119 baseline and 4.x nightly. Verified locally against SkiaSharp 4.151 and 3.119.4; a short run emits time + allocation data for every case. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: ca69afac-998b-493d-a03c-d9b25dd3f15b
Contributor
📦 Try the packages from this PRWarning 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 -- 4476PowerShell / Windows: iex "& { $(irm https://raw.githubusercontent.com/mono/SkiaSharp/main/scripts/get-skiasharp-pr.ps1) } 4476"Step 2 — Add the local NuGet source dotnet nuget add source ~/.skiasharp/hives/pr-4476/packages --name skiasharp-pr-4476More options
Or download manually from Azure Pipelines — look for the Remove the source when you're done: dotnet nuget remove source skiasharp-pr-4476 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Expand
benchmarks/SkiaSharp.Benchmarks.Trackingwith a small, curated set of permanent regression benchmarks, derived from the areas the recent perf/agentic PRs touch. Each new benchmark is one.csfile inTracking/Benchmarks/, so it's automatically picked up by both the package-mode project and the source-mode…Tracking.Sourceproject (the ⭐prcolumn).Following the project's philosophy (and how
dotnet/performance/aspnetcorestructure their suites), this is a scaled pyramid — a few small common-path trackers + one large "touch many things" indicator — not a micro-benchmark per PR.Tier 1 — small common-path trackers
ColorMathBenchmark— managedSKColor → SKColorF([performance] Port SKColor -> SKColorF conversion to managed C# #4370) +SKPMColor.PreMultiply/UnPreMultiply([performance] Port single-value SKPMColor premultiply/unpremultiply to managed C# #4385). Pure managed, zero-alloc; theToColorF/ToColorratio (the reverse operator stays native) is a clean managed-regression signal even on noisy shared runners.RasterImageLifecycleBenchmark— create+dispose churn ofSKImage.Createraster ([memory-leak] Fix CoTaskMem pixel-buffer leak in SKImage.Create raster failure path #4455) andSKData.Createwith a managed release proc ([memory-leak] Fix GCHandle leak on release-proc factory failure path #4453).MemoryDiagnoser's Allocated bytes are the tracked signal for the leak-fix area.RuntimeEffectShaderBenchmark— a per-frame animated SkSL shader: build uniforms (anSKColoruniform hits the [performance] Port SKColor -> SKColorF conversion to managed C# #4370 convert),ToShader, draw. Exercises the uniforms lifecycle whoseSKDataleak [memory-leak] Fix SKData leak in SKRuntimeEffectUniforms.Reset() #4442 fixed; per-frame allocation is the headline.Tier 2 — large composite
SceneRenderBenchmark— one broad frame (transforms, linear + radial gradients, filled/stroked primitives, a built path, a scaled image draw = the [All, critical on Windows] Severe Software (CPU) Rasterization Performance Regression / Flickering starting in Milestone 146` #4421 CPU sampling path, a colour-filter layer, clipping, managed colour maths). Deliberately broad so many unrelated future optimizations each nudge it — a merge indicator.Not added: #4372 (niche
SKNWayCanvas/SKOverdrawCanvasdebug wrappers) and #4468 (HarfBuzz — a separate assembly the tracking project doesn't reference).Constraints honoured
SkiaApi).SKPath/SKPathBuilderneeds the existing#if).Validation
Local (short job)
Built against SkiaSharp 4.151.0-preview.2.1 and 3.119.4; a
--job shortrun emits time + allocation data for every case:ColorMathBenchmark.ToColorF(managed, #4370)ColorMathBenchmark.ToColor(native reverse, sentinel)ColorMathBenchmark.PreMultiply(#4385)ColorMathBenchmark.UnPreMultiply(#4385)RasterImageLifecycleBenchmark.CreateRasterImage(#4455)RasterImageLifecycleBenchmark.CreateDataWithReleaseProc(#4453)RuntimeEffectShaderBenchmark.DrawFrame(#4442)SceneRenderBenchmark.RenderFrame(Complexity 1 / 4)(The managed
ToColorFalready measuring faster than the still-nativeToColoris the #4370 win showing through.)CI baseline —
prcolumn, run 29608575980 (2026-07-17)Full source build of this branch (the ⭐
prrole) on the GitHub-hosted runners — one point per OS, the baseline each future run diffs against. Managed allocation is OS-independent (single column). Onpr/HEADToColorFis still native, so expect its line to drop once #4370 merges.ColorMathBenchmark.ToColorF(4096)ColorMathBenchmark.ToColor(4096)ColorMathBenchmark.PreMultiply(4096)ColorMathBenchmark.UnPreMultiply(4096)RasterImageLifecycleBenchmark.CreateRasterImage(256)RasterImageLifecycleBenchmark.CreateDataWithReleaseProc(256)RuntimeEffectShaderBenchmark.DrawFrameSceneRenderBenchmark.RenderFrame(Complexity 1)SceneRenderBenchmark.RenderFrame(Complexity 4)All 21 legs green (3 OSes × source
pr+ 5 package roles incl.prev-major3.119.4); theperf-dashboardartifact renders all four benchmarks.Absolute ns are environment-dependent; the tracked signals are per-OS version-role ratios + allocations.