Follow-up from the #45 emit-backend gap audit. Three perf micro-optimizations were verified as real opportunities but are NEEDS_MEASUREMENT: every benchmark in the repo (test/perf-bench.ts, test/emit-parser-bench.ts, test/bench.ts, test/head-to-head.ts) reads the pinned /tmp/ts-repo corpus, so the project's measure-first perf discipline can't be satisfied without it. Each should be implemented byte-identical (proven by the now-CI-wired parity gates) and landed only if the corpus bench shows a win.
D1 — inline alt has no predictive dispatch
matchInto's case 'alt' (an alt inside a seq) emits a naive shared-save try-each-arm, while rule-level longest-match already has altMaskDispatch (bitmask) + SECOND refinement. FIRST-disjoint inline alts could switch-dispatch on the first token (ordered first-match is preserved when arms are FIRST-disjoint); 2-arm alts could pick the arm from the first token with no save/restore. Scale: typescript.ts ~78 alt(, javascript.ts ~43. Most substantive of the three.
C3 — SURG_ELEM table is too narrow
The node-surgery element table is built only for a pure seq/group around exactly one */+ with no alt/opt/?/multiple reps, so any list rule with an optional element or alternative (trailing comma, member list with modifiers, union body) gets no surgery and every edit inside it takes a full adoption re-parse. The audit suggests opts around the rep region may be admissible via the rowKC watermark argument — but the agent flagged uncertainty about whether the watermark check handles a [rep*, optional] kid structure, so this is the riskiest of the three and needs the surgery layout invariants worked out + exhaustive-edits confirmation (with the relaxed path asserted to fire).
B5 — lexKwT call-site length sentinel
The identifier hot path scans [pos+1, p) in the char loop, then lexKwT re-checks length-bounded keyword candidates. A top-level LX_MAXKW constant could short-circuit the call ((p - pos) > LX_MAXKW ? 0 : lexKwT(...)). Caveat found during the audit: lexKwT already bails on its first statement (if (n < minKw || n > maxKw) return 0), so the only saving is the function-call overhead for long identifiers — whether that helps depends on whether V8 already inlines lexKwT (it has a large switch). Smallest expected win; measure before bothering.
All three were left out of #45 / PR #53 precisely because landing an unmeasured perf change would violate the repo's measure-first rule, not because they aren't worth doing.
Follow-up from the #45 emit-backend gap audit. Three perf micro-optimizations were verified as real opportunities but are
NEEDS_MEASUREMENT: every benchmark in the repo (test/perf-bench.ts,test/emit-parser-bench.ts,test/bench.ts,test/head-to-head.ts) reads the pinned/tmp/ts-repocorpus, so the project's measure-first perf discipline can't be satisfied without it. Each should be implemented byte-identical (proven by the now-CI-wired parity gates) and landed only if the corpus bench shows a win.D1 — inline
althas no predictive dispatchmatchInto'scase 'alt'(analtinside a seq) emits a naive shared-save try-each-arm, while rule-level longest-match already hasaltMaskDispatch(bitmask) + SECOND refinement. FIRST-disjoint inline alts could switch-dispatch on the first token (ordered first-match is preserved when arms are FIRST-disjoint); 2-arm alts could pick the arm from the first token with no save/restore. Scale: typescript.ts ~78alt(, javascript.ts ~43. Most substantive of the three.C3 —
SURG_ELEMtable is too narrowThe node-surgery element table is built only for a pure seq/group around exactly one
*/+with noalt/opt/?/multiple reps, so any list rule with an optional element or alternative (trailing comma, member list with modifiers, union body) gets no surgery and every edit inside it takes a full adoption re-parse. The audit suggests opts around the rep region may be admissible via therowKCwatermark argument — but the agent flagged uncertainty about whether the watermark check handles a[rep*, optional]kid structure, so this is the riskiest of the three and needs the surgery layout invariants worked out +exhaustive-editsconfirmation (with the relaxed path asserted to fire).B5 —
lexKwTcall-site length sentinelThe identifier hot path scans
[pos+1, p)in the char loop, thenlexKwTre-checks length-bounded keyword candidates. A top-levelLX_MAXKWconstant could short-circuit the call ((p - pos) > LX_MAXKW ? 0 : lexKwT(...)). Caveat found during the audit:lexKwTalready bails on its first statement (if (n < minKw || n > maxKw) return 0), so the only saving is the function-call overhead for long identifiers — whether that helps depends on whether V8 already inlineslexKwT(it has a largeswitch). Smallest expected win; measure before bothering.All three were left out of #45 / PR #53 precisely because landing an unmeasured perf change would violate the repo's measure-first rule, not because they aren't worth doing.