Repository navigation
perf(photos): orient full frames by row and by tile instead of per pixel - #889
Merged
Merged
Conversation
Contributor
Wire-size diff vs merge base
Brotli q11, the quality the edge serves. Every number here is deterministic: Client assetsNo change. 26 files, 87.55 KiB Brotli total. PagesNo change. 57 files, 585.04 KiB Brotli total. Worker bundleNo change. 250.16 KiB gzip. Dictionary transportFamily dictionary acquisition: no change, 14.41 KiB q11.
|
oddharsh
added this pull request to stack #890
September 22, 2026 19:01
Base automatically changed from
claude/agentic-iteration-optimization-17c1b2
to
main
September 22, 2026 19:01
zenc's orient() re-ran the orientation match and a bounds-checked slice copy for every pixel of a 26 MP frame, and read the source down a column for the four rotations that swap axes. Flips now copy or reverse whole rows; those four rotations walk the frame in 64px tiles so each tile's source block stays in cache. Same values to the same places, so output is byte-identical. Measured 2026-09-22 on a 6240x4160 JPEG, decode-to-resample only: orientation 3 731 -> 572 ms, 6 774 -> 577 ms, 8 859 -> 601 ms. zenc:bench: identical on all 24 outputs and 258 histograms; latency 1.12-1.17x on rotated sources, upright unchanged. CPU per rotated photo -5.4 to -7.0%. The old loop stays as orient_reference, the oracle for a test over 11 frame sizes that cross tile edges; that test fails on a wrong axis and on a one-pixel tile-edge error.
pixels.rs is a declared input to images/histograms, so the orient change marks it stale. Regenerated with the new zenc (extract-photo-metadata.sh --merge over the SOOC folder, then build-histogram-index.ts): histograms.json and metadata.json were rewritten and came back byte-identical, 258 of 258 packed. Re-locked with derive:check --lock --only images/histograms. The zenc README records the pass, what orientation still costs (the copy into a fresh frame, which needs a halflight API change to remove), and a unit-test count that had read 35 against 38.
oddharsh
force-pushed
the
claude/zenc-orient-in-resample
branch
from
September 22, 2026 19:01
889d2f0 to
354bea0
Compare
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.
Stacked on #888, which carries the
zenc:benchinstrument this was measured with. Merge that first; this PR's diff is the orientation work alone.The first pass of the agentic-iteration loop on zenc.
orient()re-ran the orientationmatchand a bounds-checked slice copy for every pixel of a 26 MP frame, and for the four rotations that swap axes it read the source down a column, 75 KB between reads. 135 of 185 source photos are rotated, so it ran on nearly every ingest.The change
Same values to the same places, so output is byte-identical by construction, and the gate checks it anyway.
Measured
Decode-to-resample floor, one 6240x4160 JPEG, interleaved:
bun run zenc:bench, 7 trials, exact Mann-Whitney per source:Gate: all 24 square outputs and 258 histograms byte-identical.
Throughput is the honest caveat. At
--parallel 8the batch read 1.021x wall and 1.016x CPU, p = 0.9 and 0.3. The batch is half rotated, so the expected saving is about 2.5%, and an 8-worker pool on a machine at load 7.7 spreads CPU time ±13%. Seven batches can't resolve that. The per-photo CPU saving above is the number to trust.How the loop got here
Checks
orient_reference, the old loop verbatim, is the oracle for a new test over 11 frame sizes that cross tile edges, every orientation, gray and RGB. Mutation controls: it fails on a wrong axis (1x5, orientation 7) and on a one-pixel tile-edge error (33x65, orientation 5).images/histogramsre-locked after regenerating with the new zenc:histograms.jsonandmetadata.jsonrewritten, byte-identical.cargo test39/39, clippy-D warnings,lint,test847/0.