Skip to content

Build each edge as its own path when rendering square modules - #247

Open
mattiasgeniar wants to merge 2 commits into
Bacon:mainfrom
mattiasgeniar:perf/square-module-path
Open

mattiasgeniar wants to merge 2 commits into
Bacon:mainfrom
mattiasgeniar:perf/square-module-path

Conversation

@mattiasgeniar

Copy link
Copy Markdown

SquareModule adds every point of every edge to one big Path with move() and line(). Path is immutable, so each call copies all operations added so far, and the cost grows with the square of the number of points. This builds each edge as its own short path and appends it once, so the big path is copied once per edge instead of once per point. It also flips cells inline in EdgeIterator, instead of through two method calls per cell. The SVG output is byte-identical for 264 inputs, and the test suite has the same result as main (the two GD tests error on both here, without the extension).

Benchmark (an otpauth:// URL, the usual 2FA QR code) Before After % change
Writer::writeString(), 400 px SVG 7.16 ms 5.70 ms −20.4%
Writer::writeString(), first call 8.21 ms 6.74 ms −18.0%

Median of 15 fresh PHP 8.5 processes per side, run interleaved, opcache on. "First call" is the first run in a new process.

@mattiasgeniar
mattiasgeniar marked this pull request as ready for review November 3, 2026 18:49
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