Repository navigation
Simplify registers a candidate once, and costs a subtree once: SimplifyHard -44% allocation - #1205
Merged
Merged
Conversation
…fyHard -44% allocation Two changes, each answer-identical by construction, found by attributing SimplifyHard's 3.62 GB per call to the steps of Simplificator.Alternate with a temporary hook on AddHistory. The first is the whole of the win. AddHistory registered every candidate twice: once as it was, and once as expr.Rewrite(InvertNegativePowers) -- each registration a CanonicalOrder rewrite, an inner simplification and two ratings. On an input with no negative power to invert the second tree is the first tree, so the second registration re-sorted an identical tree, rated it again, and offered the history set an entity it already held. Measured, the registrations were 862 MB of a level's 976 MB. The second registration now runs only where the inversion produced a different tree. The second is small and free. CostModel.DefaultCost recursed through itself and scanned divisor.Nodes for every quotient, so a candidate's rating re-walked subtrees shared with every candidate before it. It recurses through Entity.DefaultCostCached now -- the slot SimplifiedRate already fills on its unset path, so the two cannot disagree -- and walks children by index, allocating nothing per node. The arithmetic is the same expression in the same order, so every rate is the same double. Measured by the inter-version benchmark on the machine the 1930th column was taken on this morning, allocation being deterministic -- and the solvers move too, because Solve simplifies inside: SimplifyHard 3,662,375,240 -> 2,027,771,744 bytes -44.6% 1.60 s -> 0.92 s SolveHard 1,452,700,104 -> 1,057,996,016 bytes -27.2% 879 ms -> 772 ms SolveMediumHard 165,611,184 -> 126,162,152 bytes -23.8% 88 ms -> 78 ms SimplifyEasy 128,460 -> 115,763 bytes -9.9% 110 us -> 89 us Every other row is unchanged or inside its floor. Timings are one run against one run on one machine and carry the file's usual rider; the allocation is the evidence. Of it the cost cache alone is -1.15% and -1.3% on the two Simplify rows. Where the rest of SimplifyHard goes is named for next time: the remaining registration (431 MB), and the three expansion candidates -- res.Expand().Simplify(-level), the rule-based factorisation at level 2, and the opened angles expanded -- at 177, 170 and 82 MB, each a recursive simplification of an expanded tree. The performance gate's baseline is updated in the same change, which its own document names as the one case where a red gate means nothing is wrong: the allocation went down. Part of #746. Full suite 9610 passed, 0 failed -- no answer moved. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura
Rafael-SOWNet
added a commit
that referenced
this pull request
Sep 7, 2026
…-64% allocation (#1207) After #1205 a SimplifyHard level was still 431 MB of candidate registration, and the same temporary hook, split by stage, said why: at level 4 there were 363 registrations of which 298 were repeats. A pass that changes nothing registers the same tree again, and each registration is a CanonicalOrder rewrite -- the Sort rules, 2.4 MB a time on this input -- and an inner simplification before the history set declines the repeat. 874 MB of sorting and 718 MB of simplifying to add nothing. Alternate keeps a set of what it has registered and AddHistory returns at once for a tree already in it. The same tree registers the same way -- the rewrite and the rating are deterministic -- so the set of candidates is what it was, and the answer with it. Measured by the inter-version benchmark on the same machine as this morning's 1930th column and this afternoon's 1931st, against the 1931st: SimplifyHard 2,027,771,744 -> 733,188,536 bytes -63.8% 924 ms -> 371 ms SolveHard 1,057,996,016 -> 859,268,416 bytes -18.8% 772 ms -> 700 ms SolveMediumHard 126,162,152 -> 94,415,256 bytes -25.2% 78 ms -> 67 ms SimplifyEasy 115,763 -> 116,291 bytes +0.5% 89 us -> 71 us Since this morning's 1930th column, SimplifyHard is -80%, SolveHard -41% and SolveMediumHard -43%. SimplifyEasy's 528 bytes more are the set itself, which on a fifteen-node input has nothing to save. Every other row is unchanged. The suite holds every pinned Simplify answer and the corpus gate. The gate's baseline is updated in the same change, for the reason its document gives for a drop. Part of #746. Full suite 9610 passed, 0 failed. Two tests re-pinned: they asserted the raw recording is twenty times the derivation path and over a hundred steps, ratios calibrated to the re-sorting this removes; it is 63 against 4 now and they say so. Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
This was referenced Sep 7, 2026
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.
Speed, measured where allocation is deterministic. Two changes, each answer-identical by
construction, found by attributing
SimplifyHard's 3.62 GB per call to the steps ofSimplificator.Alternatewith a temporary hook onAddHistory(not committed).What was found
AddHistoryitself — candidate registrationres.Expand().Simplify(-level)openedAngles.Expand().Simplify(-level)AddHistoryregistered every candidate twice: once as it was, once asexpr.Rewrite(InvertNegativePowers)— each registration aCanonicalOrderrewrite (theSortrules: 1.6 MB and 1 ms on the 473-node input alone), an inner simplification and two ratings. On
an input with nothing to invert the second tree is the first tree, so the second registration
re-sorted an identical tree, rated it again, and offered the history set an entity it already held.
What changes
candidates reach the set — a
HashSet<Entity>already deduplicated the repeat — so theselection cannot move.
CostModel.DefaultCostcosts a subtree once. It recursed through itself and scanneddivisor.Nodesfor every quotient; it now recurses throughEntity.DefaultCostCached(the slotSimplifiedRatealready fills on its unset path) and walks children by index. Same expression,same order, same doubles.
Measured
By the inter-version benchmark, on the machine the 1930th column was taken on this morning —
and the solvers move too, because
Solvesimplifies inside:SimplifyHardSolveHardSolveMediumHardSimplifyEasyEvery other row is unchanged or inside its floor. Timings are one run against one run on one
machine and carry the performance file's usual rider; the allocation is the evidence. The cost
cache alone is −1.15% / −1.3% on the two
Simplifyrows; the registration change is the rest.The gate's baseline is updated in the same change — its own document names a drop as the one case
where a red gate means nothing is wrong — and the gate passes on it.
Where the rest goes, for next time
After this a
SimplifyHardlevel is: the remaining registration 431 MB;res.Expand().Simplify(-level)177 MB; the level-2 rule-based factorisation 170 MB; the opened angles expanded 82 MB — each a
recursive simplification of an expanded tree, and each a change to what is offered rather than to
how, so not this PR.
Part of #746.
Checks
Full suite 9610 passed, 0 failed, 14 skipped — every pinned
Simplifyanswer and the corpus gate unchanged.🤖 Generated with Claude Code
https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura