Skip to content

Emit backend: three measurement-gated perf micro-optimizations (D1 / C3 / B5) #54

@johnsoncodehk

Description

@johnsoncodehk

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions