Skip to content

Keep a clip as the box it covers, not as a value for every pixel of the page - #14

Merged
tannevaled merged 1 commit into
mainfrom
bounded-clip
Aug 27, 2026
Merged

Keep a clip as the box it covers, not as a value for every pixel of the page#14
tannevaled merged 1 commit into
mainfrom
bounded-clip

Conversation

@tannevaled

Copy link
Copy Markdown
Contributor

Narrowing the clip made a float32 for every pixel of the image, whatever the shape actually covered, and did it again for every narrowing. Pages narrow their clip far more often than one would guess: a real French government form does it 2 140 times, one arXiv figure 6 711.

file size before after
fr-cerfa/cerfa_11126.pdf 1 090 815 B 9 350 MB / 16.9 s 6 036 MB / 6.8 s
2603.22026/Fig6New.pdf 566 578 B 218 762 MB / 6.6 s 719 MB / 0.7 s

304× less memory and 9× less time for the figure. A 566-kilobyte file asking for 218 gigabytes to draw one page is not a page anybody can draw twice at once.

A clip is now the box it has narrowed down to plus the coverage inside that box; narrowing intersects the boxes first, so what is stored is never larger than the smaller of the two shapes.

Proved to change nothing

3 040 corpus pages drawn before and after, every page's pixels hashed, every hash identical.

What I removed again

I also tried keeping no coverage for a clip that lets everything through inside its box — what a clip to a rectangle ought to be. It never once fired: a rectangle's edge pixels are covered fractionally, so the grid is never exactly all ones. It is not in this PR. An optimisation that does not fire is complexity with nothing to show for it.

The form's remaining 6 GB is 2 140 clips that genuinely are large; the extreme cases are what this fixes.

Found by the robustness campaign, which measured it across 33 393 render stages: median 34 MB, p99 5 618 MB, worst 97 333 MB.

Stacked on annotations. 100% statement coverage, go vet and gofmt clean, nine targets.

@tannevaled
tannevaled force-pushed the annotations branch 2 times, most recently from 36d3904 to 88c6a18 Compare August 27, 2026 08:56
…he page

Narrowing the clip made a float for every pixel of the image, whatever the
shape covered, and did it again for every narrowing. A page narrows its clip
more often than one would think: a real French government form does it two
thousand one hundred and forty times, and one arXiv figure six thousand seven
hundred.

Measured before this, drawing a single page:

  fr-cerfa/cerfa_11126.pdf     1 090 815 bytes    9 350 MB    16.9 s
  2603.22026/Fig6New.pdf         566 578 bytes  218 762 MB     6.6 s

A hundred and thirteen kilobytes of paper asking for two hundred and eighteen
gigabytes is not a page anybody can draw twice at once.

A clip is now the box it has narrowed itself down to and the coverage inside
that box. Narrowing intersects the boxes first, so what is stored is never
larger than the smaller of the two shapes, and a clip to a corner of the page
costs a corner of the page.

  fr-cerfa/cerfa_11126.pdf                        6 036 MB     6.8 s
  2603.22026/Fig6New.pdf                            719 MB     0.7 s

Three hundred and four times less memory for the figure and nine times less
time; the form is a third less and two and a half times faster, and what
remains there is two thousand large clips that genuinely are large.

Proved to change nothing: 3 040 corpus pages drawn before and after, every
page's pixels hashed, every hash identical.

I also tried keeping no coverage at all for a clip that lets everything through
inside its box, which is what a clip to a rectangle ought to be. It never once
fired on either of the files above — a rectangle's edge pixels are covered
fractionally, so the grid is never all ones — so it is not here. An
optimisation that does not fire is complexity with nothing to show for it.

Found by the robustness campaign, which measured it across 33 393 render
stages: median 34 MB, p99 5 618 MB, worst 97 333 MB.
@tannevaled
tannevaled changed the base branch from annotations to main August 27, 2026 08:58
@tannevaled
tannevaled merged commit a26b92c into main Aug 27, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant