Skip to content

mbe: literal-run fast path in the matcher; one-entry marker cache [html5ever -0.3%] - #84

Open
xmakro wants to merge 1 commit into
perf/mbe-flat-templatefrom
perf/mbe-matcher-fastpath
Open

mbe: literal-run fast path in the matcher; one-entry marker cache [html5ever -0.3%]#84
xmakro wants to merge 1 commit into
perf/mbe-flat-templatefrom
perf/mbe-matcher-fastpath

Conversation

@xmakro

@xmakro xmakro commented Aug 1, 2026

Copy link
Copy Markdown
Owner

Follow-up to #57, stacked on #83. Two independent fast paths in the mbe hot loops.

Matcher literal-run fast path. Matching stepped every literal token of an arm through the full queue machinery: a parse_tt_inner round, a queue swap, and a parser bump per token. When there is a single live matcher position and the tracker does not observe locations, a run of literal-token (and delimiter-marker) locations is now matched directly against the input:

  • once at rule start, so arms that fail on a leading literal (the common case when a macro tries its rules in order) never enter the queue machinery at all, and
  • again whenever a matched token leaves exactly one next position.

Failure values and token positions are identical to the queue path, matching stops at input Eof so the distinct missing-tokens diagnostic still comes from the queue path, and tracking invocations (the diagnostics retry pass) are gated out via a new Tracker::NEEDS_TRACKING const, so they observe every location exactly as before.

One-entry marker cache. Marking spans during transcription hashed the syntax context into the marker cache for every token. A one-entry cache in front of the map now hits on a plain compare, since virtually all tokens in a macro body share one syntax context.

Performance (ThinLTO stage2, jemalloc, instructions:u, full scenario, measured on top of the perf stack; base includes #82+#83):

  • html5ever check -0.27%, debug -0.21%; clap_derive check -0.13%; deep-vector -0.13%; serde/syn -0.06 to -0.07%
  • tt-muncher -0.17% (the matcher fast path is placement-sensitive: a per-token variant reached html5ever -1.06% but cost tt-muncher +1.95%; the shipped placement takes the safe side, and a per-matcher precomputed gate could reclaim the rest as future work)
  • only counter-move: token-stream-stress debug +0.38% on a 150M-instruction stress cell (+568K instructions absolute, consistent across matcher-design variants, likely code layout)

Correctness: stage2 green; x check compiler green standalone on this branch; full tests/ui failure set byte-identical to the pre-existing baseline (21301 passed, zero new diffs), which includes the macro diagnostics tests exercising the tracking path.

Matching stepped every literal token through the full queue machinery:
a round of parse_tt_inner plus a queue swap and a parser bump per
token. When there is a single live matcher position and the tracker
does not observe locations, a run of literal-token locations is now
matched directly against the input: once at rule start, so arms that
fail on a leading literal never enter the queue at all, and again
whenever a matched token leaves a single next position. Failure
values and positions are identical to the queue path, and tracking
invocations (the diagnostics retry) never take the fast path.

Marking spans during transcription hashed the syntax context on every
token; a one-entry cache in front of the map now hits on a plain
compare, since virtually all tokens in a macro body share one context.

html5ever check -0.27%, clap_derive check -0.13%, no real-world
regressions.
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