perf(scripts): add a device-free PNG crop benchmark - #2505
Conversation
|
Size Report
Startup median (7 runs, lower is better):
|
|
The benchmark compares different execution paths at acabc0f: Coverage also fails the five eager-import budget checks inherited from #2504. Resolve those in the lower PR before merging this layer. This head now conflicts with its updated base. Reconcile it with #2504 before merging. |
46cfcd1 to
910b2d4
Compare
910b2d4 to
4749932
Compare
|
Commit identity: this layer's head is Matched boundary. Both pipelines now run as PNG worker jobs over the same bytes in one process. Updated numbers, 7 rounds at that boundary over three real captures, replacing the 1.9x to 5.1x this PR quoted, which was measured across the mismatched boundary:
The README says that losing case plainly instead of averaging it away: inflating and reconstructing that much entropy dominates both pipelines, and the Scope wording. A "What is actually saved" section says neither pipeline reads less of the file, because a deflate stream has to be inflated to its end; what stops at the box is reconstruction and allocation, plus one worker round trip and the RGBA re-encode. The reader's module doc says the same thing where the code is. Eager-import budgets were inherited from #2504 and are resolved there at |
4749932 to
3b121f7
Compare
|
The benchmark correction is sound at 3b121f7: both pipelines now use the shipped worker boundaries, and the documentation states the full inflate cost and the reported noisy-capture tradeoff. No code findings in this layer; current-head checks pass and its base conflict is resolved. Merge still depends on resolving the remaining parser finding and readiness requirements in #2504. |
`pnpm bench:png-crop` runs the whole-image pipeline and the shipped region crop over the same bytes in one process, so the comparison holds the capture content, the deflate stream, and the machine fixed. The corpus is generated, which keeps a run at seconds with no device; real captures join the same table via `--file`, and each corpus entry prints its compressed size so an unrealistic corpus is visible. The README records what the measurements said, including the case the encoder policy loses: `None` on every scanline is faster everywhere but writes about 1.7x more bytes than a filtered encoding on smooth low-frequency content.
Registers scripts/png-crop-benchmark/*.test.ts so the timing summary that the report is built from stays covered without a device lane.
3b121f7 to
03baaa5
Compare
|
Nothing to change in this layer, so it is unchanged: the head is The description's validation section now names these heads instead of an earlier push. Local |
|
The benchmark layer remains code-clean at 03baaa5; its logical patch is unchanged by the rebase onto the corrected PNG reader. There are no conflicts. The remaining prerequisite is #2504’s size decision. The current iOS failure is the alert-replacement test reaching its deadline before activation, which appears unrelated to this tooling layer and still needs to pass before merge. |
Summary
Adds
pnpm bench:png-crop, which runs both crop pipelines over the same bytes as PNG worker jobs in one process, so content, deflate stream, thread and machine stay fixed. Both sides pay the job round trip the shipped command pays:whole-image— the previous crop: one job decodes the whole capture to RGBA, the box rows are copied out of that bitmap, a second job encodes the box.region— the shipped crop: one job reads the box's rows and encodes them.Neither writes a file; publishing the artifact is the same work on both sides, so it would only dilute the ratio, and each row reports the encoded byte length instead. Neither side reads less of the capture either: a deflate stream has to be inflated to its end, so both inflate the whole compressed image, and the region path inflates it into a buffer sized for every filtered row. What stops at the box is the pixel work.
Six generated captures at iPhone, Android-phone and iPad resolutions cross three crop-box shapes (
card,header,control) that match what--crop-onresolves.The corpus is generated, so a run costs seconds with no device. Every corpus entry prints its own compressed size against a real capture's, which is how a corpus that stopped resembling a device becomes visible instead of flattering. Real captures join the same table with
--file, and they decide the verdict.12 files, 581 gross lines: ten new tooling files plus one package script and one gate registration; no production path is touched.
Validation
Validated at the stack head
03baaa59c3, on base71a4386108from #2504. This layer carries no production code; the parser fix and the live Android crop evidence landed in the lower layer.pnpm check:affected --runruns 368 test files / 2,350 tests plus format, oxlint, typecheck, layering, di-seams and the eager-closure budget suite clean.mutation-modelandproduction-exportsfail identically atorigin/mainin this worktree (63 export findings at the merge base, none inpng-*orscripts/png-crop-benchmark) — pre-existing, unrelated.pnpm check:fallow --base origin/mainreports no issues in 29 changed files.scripts/png-crop-benchmark/*.test.ts(12 tests) run inunit-corevia thechore(gates)commit here.Numbers quoted in the README come from 7-round runs at this commit over three real captures: 2.6x to 5.6x faster and up to 2.16x smaller on a 245 kB iOS UI capture, 1.78x to 2.52x faster and up to 1.31x smaller on a 3 MB iOS photo capture, and a wash on time (0.98x to 1.64x) with a crop up to ~13% larger on a noisy 1.4 MB Android
screencap. The README states that losing case rather than averaging it away, and says to check your own captures with--filebefore reading a win or a loss into any number here.