Skip to content

The reason the canonical orders stay a switch is a third of what it was - #1086

Merged
Rafael-SOWNet merged 1 commit into
masterfrom
feat/canonical-order-is-data
Aug 26, 2026
Merged

The reason the canonical orders stay a switch is a third of what it was#1086
Rafael-SOWNet merged 1 commit into
masterfrom
feat/canonical-order-is-data

Conversation

@Rafael-SOWNet

Copy link
Copy Markdown
Collaborator

Documentation only — no behaviour change, no wiring change.

MatchedRules.Sort records why it is expressed as data and not wired: paying matcher
dispatch on the normalisation cost +48% of SimplifyEasy, which the kernel gate
reported as 4.14x on a shared runner (#1073).

That figure was measured, and it was a statement about the matcher of the day. The matcher
has changed twice since — bounded matching (#1080) and rules indexed by node type (#1085).
Wiring the three canonical orders again today:

SimplifyEasy allocated
master (8c5157b2) 97,048 ns 128,100 B
the three orders as data 109,968 ns — +13.3% 128,460 B — +0.28%

The decision does not move. 13% of the flagship benchmark for no capability is still
no, and allocation is now inside the gate's band where the cost used to be the gate itself.
What moves is the reason — and what the reason is about.

It is no longer dispatch

Every rule in this set is typed — Any<Sumf>, Any<Mulf> — so #1085's index tries one or
two rules at a node, not seven. What is left is the layer itself: a rule is a match that
binds a name plus a delegate that reads it back, where a switch arm is a type test and a
call.

Everywhere else that layer buys something — a pattern that says what the rewrite is,
reversible, addressable, checkable against the arms. Here every rule is a type test and a
call already
, so there is nothing for it to buy.

That is a better boundary than "the normalisation is too hot": it is about what a rule is,
not about where it runs. A set whose rules are really patterns is free or better —
Common, sixty-two rules on the same hot path, is −4.1% (#1083).

The remark now also says the number has to be re-measured when the matcher changes, because
this is the second measurement and the first had been read as settled.

Part of #746 tier 1.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Bjumi5K7fg8yx6UK1mZTQd

… was

`MatchedRules.Sort` records why it is expressed and not wired: paying matcher dispatch
on the normalisation cost +48% of `SimplifyEasy`, which the kernel gate reported as
4.14x. That figure was measured, and it was a statement about the matcher of the day.
The matcher has changed twice since -- bounded matching (#1080) and rules indexed by
node type (#1085) -- and the same wiring now measures **+13.3%**: 97,048 ns to
109,968 ns on the repository's own benchmark, allocation +0.28% and inside the band.

The decision does not move. Thirteen percent of the flagship benchmark for no capability
is still no. What moves is the reason, and what it is a reason *about*.

It is not dispatch across the rules any more. Every rule in this set is typed --
`Any<Sumf>`, `Any<Mulf>` -- so the index tries one or two at a node rather than seven.
What is left is the layer: a rule is a match that binds a name and a delegate that reads
it back, where a `switch` arm is a type test and a call. Everywhere else that layer buys
something -- a pattern that says what the rewrite is, reversible, addressable. Here every
rule is a type test and a call *already*, so there is nothing for it to buy.

That is a better boundary than "the normalisation is too hot", and it is about what a
rule is rather than about where it runs. It also has to be re-measured whenever the
matcher changes, which is now written down, because this is the second measurement and
the first one had been read as settled.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Bjumi5K7fg8yx6UK1mZTQd
@Rafael-SOWNet
Rafael-SOWNet merged commit 2934dcc into master Aug 26, 2026
31 checks passed
@Rafael-SOWNet
Rafael-SOWNet deleted the feat/canonical-order-is-data branch August 26, 2026 21:08
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