chore(benchmarks): time the preview pipeline, stage by stage - #499
Conversation
9a3962b to
97b8c7e
Compare
|
Reworked as a neutral pipeline probe, and rebased onto Your blocker was right, and it was mine to make: the probe measured the pipeline correctly and then interpreted it as a bound on a design that does not exist yet. Both stages I called fixed are nothing of the sort — Removed: The three measurement fixes, and what they cost:
Current output: The gap between the summed stages and
|
DocumentSession.toImages(dpi) reaches a raster through compose, layout, building a PDDocument and saving it to bytes, Loader.loadPDF, and PDFRenderer. The probe times each of those separately, warm, on two canonical workloads, so the shape of the cost is measured rather than assumed. It deliberately draws no conclusion about a direct Java2D backend. The encode stage is not serialisation — before save() the backend creates pages, walks the whole LayoutGraph, paints every fragment, resolves links and bookmarks and applies the page chrome. The PDFRenderer stage is not pixel production alone — it interprets PDF operators and then paints them through Java2D. A direct renderer would change work in both stages, so no stage here is removable, and no measurement of this pipeline predicts the cost of a different one. That comparison needs a second implementation. Three measurement details the numbers depend on: - every DPI renders from a freshly parsed document and its own PDFRenderer, because sharing one hands each later DPI the caches the first one warmed — measured at 13% on the CV and 28% on the proposal; - toImages runs on its own sessions rather than after four raster passes over the same document, in both the layout-cached and from-scratch case; - totals are summed inside an iteration and the median taken of those, since medians of separate stages do not add to the median of their sum. It joins the probe family already in this module — AllocationRateProbe, AutoSizeMeasureProbe, ChartAllocProbe, FontEmbedProbe — reuses CanonicalBenchmarkSupport, reads nothing private and changes no src/main code. benchmarks is a development module and ships to no registry. Run end to end, exit 0.
97b8c7e to
b49b8ed
Compare
Why
DocumentSession.toImages(dpi)reaches a raster through a chain of stages — open thesession, compose, layout, build a
PDDocumentandsave()it to bytes,Loader.loadPDF,PDFRenderer— and the cost of each was assumed rather than measured. A probe thatprints them is the cheapest way to stop guessing.
An earlier revision of this branch drew a conclusion from those numbers: that a direct
Java2D backend would delete three stages and leave rasterisation untouched, bounding the
win at a few milliseconds. That was wrong on both halves, and the probe now says so in
its own Javadoc rather than in a commit message nobody reads:
save()the backend creates pages, walksthe whole
LayoutGraph, paints every fragment, resolves links and bookmarks, andapplies headers, footers, metadata, watermark and protection. A direct renderer
replaces that painting work; it does not delete it.
and then paints through Java2D. A direct renderer skips the interpretation and keeps
the painting.
A direct backend therefore changes work in both stages, so no measurement of the present
pipeline can predict the result. Comparing the two designs needs a second implementation
to measure against — which is exactly what this probe does not substitute for.
What
One new file,
benchmarks/.../PreviewCostProbe.java. It reports each stage warm, as amedian with min/max, on two canonical workloads (a one-page CV and a three-page proposal).
Measurement decisions worth naming:
PDFRenderer, so a laterDPI does not inherit the glyph and resource caches an earlier one warmed. The parse
sits outside the timed region.
toImagesis measured on its own sessions rather than after four raster passes overthe same document.
services before a single node is composed, and folding that into the compose figure
attributed engine setup to the DSL — on the CV workload it was roughly a fifth of what
the probe called "compose".
totals rather than a sum of independent medians.
Tests
./mvnw -B -ntp clean verify→BUILD SUCCESS. The probe itself was run; both workloadsreport, and the
sum of the stagesrow tracks the measuredtoImagesfigure it is meantto account for (CV: 17.29 ms sum vs 17.04 ms fresh-session
toImages).This is a probe, not a gate: it is a
maininbenchmarks/, run on demand, and nothingin CI depends on its numbers.