Skip to content

Release 0.1.12: skip alternatives that cannot begin here (first-character BRANCH) - #4

Merged
proggeramlug merged 1 commit into
mainfrom
branch-first-char-dispatch
Oct 8, 2026
Merged

proggeramlug merged 1 commit into
mainfrom
branch-first-char-dispatch

Conversation

@proggeramlug

@proggeramlug proggeramlug commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Release 0.1.12: alternatives that cannot begin at the current character are skipped without pushing a frame. Program format 14; format-13 programs are rejected on load.

Why: Claude Code's emoji-width regex, a large alternation run once per grapheme, cost about 2,200 instructions per search. Anatomy of 0.1.11, from exact callgrind counts:

  • whether the pattern is anchored was re-derived on every search (31 instructions on small patterns, 313 on the emoji pattern);
  • alternation was compiled as a left-nested chain, so 10 backtracking frames were pushed before the first alternative was tried, and nothing skipped alternatives that can't start with the next character;
  • every start cleared 390 registers, one per ? repeat;
  • the program header was compared with memcmp.

Changes:

  • Alternation is laid out flat, with one live frame per alternative tried.
  • A new BRANCH instruction carries the first-character set of its alternative, derived from the compiled code and checked again on load. Alternatives that cannot start here are skipped without a frame, and a chain of them is decided from one read.
  • The anchored check moves into the program header and is checked on load.
  • A search clears only the capture registers.
  • The header comparison is inline.
  • Write-up: docs/branch.md.

Standalone instructions per search (0.1.11 → 0.1.12; both columns include about 65 instructions of bench-loop overhead):

case 0.1.11 0.1.12
emoji, cc grapheme mix 2,212 946 (−57%)
emoji on 1 6,664 2,569 (−61%)
emoji on 中 6,741 1,637 (−76%)
emoji on 😀 (match) 11,014 5,638 (−49%)
^\p{DI}$, cc mix 432 391 (−9.5%)
/ab|cd|ef|gh/ 3,183 2,124 (−33%)
/a/ hit 1,206 1,162 (−3.6%)

No measured case got slower. The full 19-row table is in docs/branch.md.

Tests:

  • cargo test in debug and release: 211/0. clippy with -D warnings, fmt --check and the Unicode table generators' --check all pass.
  • All 44 Node differential jobs that CI runs show 0 differences, including test262 (48,718 cases), paused runs at quanta 1 and 17 with relocation and growth, and the native-tier check.
  • New tests/branch.rs with 5 tests. Six injected faults each make the suite fail.

Not published to crates.io. Perry then needs only perex = "0.1.12". The measurement inside perry (micros, program set) follows before that bump.

Summary by CodeRabbit

  • New Features

    • Search programs now use format version 14, with faster handling of alternatives that can be ruled out by the next character.
    • Start-anchored search information is stored and validated in the program.
  • Documentation

    • Added details on alternative filtering, anchoring, format changes, and performance benchmarks.

…ut a frame

Alternation is laid out flat instead of left-nested, so one frame is live per
attempted alternative and a success leaves through one jump. A new BRANCH
instruction carries the first-character set of its first arm (32 buckets,
derived from the emitted instructions and re-derived on validation); when the
next character is outside it the arm and its frame are skipped, and a chain of
such branches is decided against one read. The start-anchored claim is stored
as a validated word 7 bit instead of being derived on every search, and a
trial clears only its capture registers: repeat registers are written by
REPEAT_INIT before anything reads them. Program format 14; format 13 is
rejected.

Engine instructions per search vs 0.1.11 (Search::run over counted bindings):
the emoji-regex pattern on one-character graphemes -57.2% (on a digit -61.4%,
on a letter -44.2%), /^\p{DI}$/u on the same -9.5%, /ab|cd|ef|gh/ -33.3%,
/(foo|bar|baz)=(\d+)/ -10.0%, /a/ hit and miss -3.6% and -9.0%; no measured
case slower. See docs/branch.md.
@coderabbitai

coderabbitai Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 31a00d5c-f912-4ec1-a29c-21e7ba8a3c99
📥 Commits

Reviewing files that changed from the base of the PR and between 80845f5 and 03a4598.

⛔ Files ignored due to path filters (2)
  • Cargo.lock is excluded by !**/*.lock
  • bench/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (18)
  • CLAUDE.md
  • Cargo.toml
  • README.md
  • docs/branch.md
  • docs/candidate.md
  • docs/engine.md
  • docs/leading.md
  • src/binding.rs
  • src/compiler/prepared.rs
  • src/executor.rs
  • src/executor/admission.rs
  • src/executor/candidate.rs
  • src/program.rs
  • tests/atom_repeat.rs
  • tests/branch.rs
  • tests/candidate.rs
  • tests/classes.rs
  • tests/modifiers.rs

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The program format advances to version 14. The compiler emits flattened alternations and eligible BRANCH instructions with first-character masks. Validation checks the masks and stored anchoring claim. Search execution uses the masks to skip alternatives and reads the stored anchoring claim.

Changes

Format 14 metadata and validation

Layer / File(s) Summary
Format metadata and validation
src/program.rs, src/binding.rs, docs/candidate.md, docs/engine.md, docs/leading.md, CLAUDE.md, Cargo.toml, tests/*
The program format advances to version 14. Validation derives and checks branch masks and the stored start-anchored claim. Bound-program header checks use same_header. Version references and related expectations are updated.
Flattened alternations and branch emission
src/compiler/prepared.rs, tests/branch.rs, README.md, docs/branch.md
The compiler emits ordered alternations as a flat chain and changes eligible forward SPLIT instructions to BRANCH instructions with derived masks. Tests check instruction layout and alternative order.
Search execution and verification
src/executor.rs, src/executor/*, tests/branch.rs, docs/branch.md
The executor skips alternatives when the next character is outside their masks and charges work for skipped branches. Trial initialization clears capture registers. Search and candidate paths use the stored anchoring claim and shared branch traversal. Tests compare search results and check anchored searches, register initialization, and validation mutations.

Priority: ➖ Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Refactor

Sequence Diagram(s)

sequenceDiagram
  participant Prepared
  participant ProgramValidation
  participant Executor
  participant Input
  Prepared->>ProgramValidation: Emit BRANCH instruction and first-character mask
  ProgramValidation->>ProgramValidation: Derive and validate stored mask
  Input->>Executor: Provide next input character
  Executor->>Executor: Compare character bucket with branch mask
  Executor->>Executor: Skip excluded alternative or push backtracking frame
Loading

Merge Risk: ⚪ Minimal · up to 03a45

This release adds first-character branch filtering and moves the program format to version 14. Format-13 programs are rejected on load. No concrete defect was identified, and the reported test and differential results indicate no behavior change in match answers. The change looks ready to merge.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 77.50% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 40 functions across 11 files. (7 skipped:… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the 0.1.12 release and the primary change: using first-character BRANCH instructions to skip alternatives that cannot match.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Full details: Docstring Coverage

Explanation

Docstring coverage is 77.50% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 40 functions across 11 files. (7 skipped: 7 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@proggeramlug
proggeramlug merged commit b97fa7c into main Oct 8, 2026
7 checks passed
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