Skip to content

The performance pair for 2.2.0, and what it caught (#746) - #939

Merged
Rafael-SOWNet merged 1 commit into
masterfrom
perf/2-2-0-column
Aug 14, 2026
Merged

The performance pair for 2.2.0, and what it caught (#746)#939
Rafael-SOWNet merged 1 commit into
masterfrom
perf/2-2-0-column

Conversation

@Rafael-SOWNet

Copy link
Copy Markdown
Collaborator

#746 makes a measured performance column a standing condition of a release rather than a roadmap item, and 2.0.0 shipped without one. This is the pair for 2.2.0.

The 1709th, tagged v2.1.0, against the 1724th — measured minutes apart in one session on one machine, so the two may be read against each other.

Four solver rows moved, and the allocation moved with them

1709 (v2.1.0) 1724 (master) time allocation
SolveEasyMedium 23,509 ns 28,503 ns +21.2% +19.6%
SolveMediumHard 74.9 ms 85.4 ms +14.0% +10.4%
SolveMedium 411,557 ns 461,734 ns +12.2% +18.7%
SolveHard 800.2 ms 858.0 ms +7.2% +9.6%

Everything else is flat — ParseEasy +0.0%, SimplifyEasy −0.5%, EvalTrig −0.8%, the Run* trio within 2%, allocation byte-identical on most rows.

Allocation moving with the timing is what makes it real. The previous pair is the cautionary case: a row reported +8.7% with allocation flat, and re-measuring put it at +2.1%. Here four related rows move together in both, which noise does not do.

It is #918, the polynomial layer, and it is a price rather than a regression

Isolated by measuring the commits either side of it. Allocation steps exactly once:

SolveMedium, allocated
the 1709th, v2.1.0 554,368 B
51194ce8, before #918 554,368 B
69f66da7, after #918 658,259 B
the 1724th 658,259 B

The same clean step in all four rows. SolveEasy — a quadratic, which never reaches the factorisation path — is flat throughout, which is the mechanism corroborating itself.

#918 made the equation solver the polynomial layer's first consumer, which is what turned x^5 + 2x^3 - 2x^2 - 4 from three roots, one of them a float, into all five, exact. An incomplete solution set is a false answer, not a partial one, so the trade is the one AGENTS.md's first rule requires. Recorded, not fixed.

What the suite cannot see, which is worth more than the rows it can

None of these ten solver benchmarks benefit from #918. They are quadratics, a substituted quadratic and a trigonometric substitution; not one factors into lower-degree pieces, so every one pays the search and none collects the answer. The column shows the change as pure cost — true of these inputs, false of the change.

A benchmark whose polynomial does factor is owed before the next column, or this row will keep reporting a correctness fix as a slowdown for as long as anyone reads it.

Documentation only — no code changes.

🤖 Generated with Claude Code

#746 makes a measured performance column a standing condition of a release rather than a roadmap
item, and 2.0.0 shipped without one. This is the pair for 2.2.0: the 1709th, tagged v2.1.0, against
the 1724th, measured minutes apart in one session on one machine so that the two may be read against
each other.

Everything that is not the solver is flat -- parse, simplify, evaluate and the compiled-call trio
within 2%, allocation byte-identical on most rows. Four Solve rows are 7% to 21% slower and allocate
10% to 20% more.

**Allocation moving with the timing is what makes it real.** The previous pair is the cautionary
case: a row reported +8.7% with allocation flat and re-measuring put it at +2.1%. Here four related
rows move together in both, which noise does not do.

Isolated to #918, the polynomial layer, by measuring the commits either side of it: allocation steps
exactly once, at that commit, and is identical to v2.1.0 before it and to master after it, in all
four rows. SolveEasy -- a quadratic, which never reaches the factorisation path -- is flat
throughout, which is the mechanism corroborating itself.

**It is a price rather than a regression.** #918 made the equation solver the polynomial layer's
first consumer, which is what turned x^5 + 2x^3 - 2x^2 - 4 from three roots, one of them a float,
into all five, exact. An incomplete solution set is a false answer, not a partial one, so the trade
is the one AGENTS.md's first rule requires. Recorded, not fixed.

And the part worth more than the rows: **none of these ten solver benchmarks benefit from #918.**
They are quadratics, a substituted quadratic and a trigonometric substitution; not one factors into
lower-degree pieces, so every one pays the search and none collects the answer. The column shows the
change as pure cost, which is true of these inputs and false of the change. A benchmark whose
polynomial does factor is owed before the next column.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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