mirror of
https://github.com/storytold/photocraft.git
synced 2026-10-25 15:34:49 +01:00
* perf(seam): drop the original-column map from the shrink proxy, same pixels (-15 % at 24 MP) Content-Aware Scale's proxy seam search tracked each panel column's original column in an idx map, one usize per proxy pixel, shifted by every seam. The original column is x plus the number of columns already taken at or left of it, so a per-row list of the taken columns answers the same question without a buffer the size of the energy map. The recorded P28 budget number predates the proxies: the 2026-10-05 baseline commit carves at full height and recomputes energy per seam, and measures 266 s for the 24 MP case on the machine this was timed on, against 2.6 s now. Documented in docs/seam-carving-performance.md; enforce stays off until a budgeted-class run can vouch for the whole row. * review: generate exactly ch samples per pixel in bench_seam, reject ch > 4 The fixture flattened four samples per pixel and then truncated to w*h*ch, so a three-channel run grouped samples across pixel boundaries and any ch above four built a buffer shorter than the rows carve_width indexes. Generate ch samples inside the per-pixel closure and refuse ch outside 1..=4. The three-channel row is dropped from the perf note rather than re-measured here: it moved inside the timer noise either way, and the other agents' builds on this machine make a fresh number worthless. The four-channel hashes are unchanged, which is the check that this edit touched only the fixture. * perf(seam): find the removed column by binary search, not a linear scan Recording a seam recovered each removed original column by scanning the row's list of already-taken columns, so a deep shrink paid a comparison per removed column on every row and every seam: quadratic in the seam count, and worse than the index map this PR replaced once a shrink got deep enough. `o - i` never decreases along the row's sorted list, so that count is a binary search, and the original column belongs where the search stopped; the rows are independent and update in parallel, like the pixel shift. What is left per removed column is one insert. Output is unchanged: same columns, same order, same hashes (10 % and 50 % width cases below), and `counted_removed_columns_match_the_tracked_map` now runs a tracking and a counting carver side by side to one column and compares every row's list after every seam. docs/seam-carving-performance.md gains those cases, states that the ~104x figure is the two example runs rather than the baseline row, and names perf/baseline.json as the source of the 954 s. --------- Co-authored-by: ebosido444-ai <ebosido444-ai@users.noreply.github.com>