commit e77764449b12af05837424a0441861d5f29aee6b
parent a4ff4c6cd46cad0d2e356bd9c5389677c183e84f
Author: Ryan Sepassi <rsepassi@gmail.com>
Date: Thu, 11 Jun 2026 11:51:31 -0700
docs(perf): record the keyword classify-once CSE result
parse_decl_specs now classifies each token's keyword identity exactly
once (+7.4% type-decl, byte-identical); the same CSE on the statement
dispatch measured neutral (already-cheap direct compares). Notes the
deeper Sym-table variant is unnecessary.
Diffstat:
1 file changed, 12 insertions(+), 6 deletions(-)
diff --git a/doc/plan/PERF.md b/doc/plan/PERF.md
@@ -188,12 +188,18 @@ design). Ranked by (impact × confidence) / risk:
append into the lexer's hot loop** (publish the append cursor so a
static-inline fast path does one bounds-compare + store, out-of-line only on
grow). The clean 16 B `Tok` foundation is the prerequisite and is done.
-3. **Keyword-id on the `Sym`** — a deeper, also-byte-identical variant of the
- landed parser `KwMap`: it CSEs the ~30-call `is_kw` chain in `parse_decl_specs`
- through one classification (the map alone leaves that chain doing per-`k`
- probes). Measured ~10.5 % frontend-CPU on type-decl. A swap-in for the current
- `KwMap` (they touch the same `ident_kw_inline`/`is_kw` lines, so only one
- lands).
+3. **Keyword classify-once** — *partly landed.* The real residual the `KwMap`
+ missed was `parse_decl_specs` re-deciding keyword-ness ~27×/token (26 `is_kw`
+ + a trailing `ident_kw`); a single alias-aware `classify_kw()` at the loop top
+ captured it byte-identically: **+7.4 % type-decl** (cumulative type-decl now
+ +15.6 % vs pre-Round-6). The same CSE on the *statement* dispatch measured
+ **neutral** — that chain was already 13 cheap direct compares with no alias
+ keywords, so routing it through one `classify_kw` (a hashmap probe) just trades
+ compares for a probe. The full invariant (one classification per token, cached
+ on the parser at `advance`-time so every site reads a field) would dedup the
+ remaining label-check + dispatch probes, but measured not worth the refactor at
+ the cheap sites. The deeper keyword-id-on-`Sym` table is **not** needed — the
+ classify-once CSE captured the win without it.
**Deliberately not pursued** (measured dead ends, keep them dead):
**fused lex→pp→parse** (a pull pipeline that never materializes a `Tok` array) —