A sum, difference, product, quotient, conjunction, disjunction, exclusive disjunction, union or intersection caches the flat list of its operands, and SimplifyHard allocates 5.2% less - #1426
Conversation
|
Are these the only LinearChildren properties? How about And/Or/Xor? |
|
No — five more, and I had missed them: |
…sive disjunction, union or intersection caches the flat list of its operands, and SimplifyHard allocates 5.2% less #224. LinearChildren flattened a nested sum or product into a lazy chain of Concat and Select enumerables, built afresh on every enumeration -- and a difference's subtracted terms were each multiplied by -1 anew, a quotient's divisor factors each raised to -1 anew -- while every rule that reads a sum as a list reads it again for every candidate. A node is immutable, so the flat list is a property of the node: it is built once, as an array, from its parts' own cached lists, and handed out as an IReadOnlyList<Entity> from then on. Memory is linear in the tree, since a nested node's array is built from the arrays cached on its children rather than by walking down again, and no enumeration is repeated. The same for the five other associative chains -- and, or, xor, unite, intersect -- whose flatteners in Functions/Boolean/Simplifier.cs had the same lazy shape behind a generic branch getter, and read by the sort-and-group rules. The benchmark gate measured it: with the sum and product caches alone SimplifyHard allocates 171,275,272 B per operation against the 181,019,056 B recorded at 6e5986a, 5.4% less, and 8.1% less than the 186,284,672 B of the commit before this one; the five connective caches put 334,536 B back (+0.2%), the arrays of chains flattened once outweighing the enumerations they save, so the whole is 171,609,808 B, 5.2% less. The other eighteen gated rows are within tolerance, ParseHard carrying the +1.6% the quantifier grammar cost in #1421. Recorded in performance-baseline.json in the same change, as the gate's own instructions say an improvement must be. Also corrects the Modf record's summary, which said the remainder takes the sign of the dividend as C#'s % does: it is the floored remainder, (-7) mod 3 is 2, as the evaluation and Syntax.md have said since #708. Closes #224. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura
178efe9 to
5c4a7d9
Compare
|
Done in |
#224, per the comment there: "just simple optimization for the agent".
Sumf.LinearChildrenandMulf.LinearChildren— and, as asked below, the five flatteners of the same shape forand,or,xor,uniteandintersectinFunctions/Boolean/Simplifier.cs, read by the sort-and-group and push-not-inside rules — flattened a nested sum or product into a lazy chain ofConcat/Selectenumerables, rebuilt on every enumeration — a difference's subtracted terms each multiplied by-1anew, a quotient's divisor factors each raised to-1anew — and every rule that reads a sum as a list reads it again for every candidate. A node is immutable, so the flat list is a property of the node: it is now built once, as an array, from its parts' own cached lists (LazyPropertyA, the same cache the other per-node properties use), and handed out as anIReadOnlyList<Entity>. Memory is linear in the tree, since a nested node's array comes from the arrays cached on its children rather than from walking down again, which is the "redistribute with linear memory" of the issue's sketch.Measured by the gate, which failed as it should on an improvement:
6e5986a7)89d3b0a7)Of that, the sum/product caches alone are 171,275,272 B; the five connective caches put 334,536 B (+0.2%) back — the arrays of chains that are flattened once outweigh the enumerations they save on this benchmark — and are in for uniformity: one rule for what a flattener is, and the generic
IBranchGettermachinery (which its own comment called awful) gone.The other eighteen gated rows are inside tolerance (ParseHard carries the +1.6% the quantifier grammar cost in #1421; Derivate +1.9%, the one-time array on a node that is flattened once and read once).
performance-baseline.jsonis updated in the same change, asversion_performance_control.mdsays an improvement must be, with the commit and date it was measured at.Also corrects the
Modfrecord's summary, which claimed the remainder follows the dividend's sign as C#'s%does; it is the floored remainder ((-7) mod 3is2), as the evaluation andSyntax.mdhave said since #708 — a stale comment, not a behaviour change.Full suite 11890 passed, 0 failed.
Closes #224.
🤖 Generated with Claude Code
https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura