perf(parser): use range checks for is_any_keyword() and is_number()#14410
perf(parser): use range checks for is_any_keyword() and is_number()#14410graphite-app[bot] merged 1 commit intomainfrom
Conversation
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. |
There was a problem hiding this comment.
Pull Request Overview
This PR optimizes two hot path functions in the lexer by replacing multiple enum variant checks with efficient range checks. The optimization leverages the contiguous layout of keywords and numeric literals in the enum to reduce assembly instructions.
- Replaced multi-function calls in
is_any_keyword()with a single range check - Simplified
is_number()from matching 11 variants to a range check - Added unit tests to verify enum contiguity assumptions
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
CodSpeed Performance ReportMerging #14410 will not alter performanceComparing Summary
|
05689d7 to
9598a9e
Compare
Merge activity
|
…14410) ## Summary Replace multi-function calls and multiple enum variant checks with simple range checks, reducing assembly instructions in hot paths. ## Changes ### `is_any_keyword()` **Before**: Called 4 separate functions checking 70+ enum variants: - `is_reserved_keyword()` - 38 variants - `is_contextual_keyword()` - 39 variants - `is_strict_mode_contextual_keyword()` - 8 variants - `is_future_reserved_keyword()` - 7 variants **After**: Single range check `Await..=Yield` since all keywords are contiguous in the enum ### `is_number()` **Before**: Matched 11 separate enum variants **After**: Single range check `Decimal..=HexBigInt` since numeric literals are contiguous ## Assembly Analysis ### Before (with scattered checks) ```asm mov x8, #992 ; Load bitmask constant movk x8, #992, lsl #16 ; More bitmask setup movk x8, #240, lsl #32 ; Even more bitmask setup lsr x8, x8, x0 ; Shift by kind value and w0, w8, #0x1 ; Extract result bit ``` **5 instructions** with complex constant loading ### After (with range check) ```asm and w8, w0, #0xff ; Extract byte sub w8, w8, #5 ; Subtract range start cmp w8, #39 ; Compare to range size cset w0, lo ; Set result ``` **4 instructions** with simple arithmetic ## Performance Impact - **20% fewer instructions** (5 → 4) - **Simpler logic** = better CPU pipeline utilization - **No complex constants** = smaller code size - **Better branch prediction** with single comparison This is particularly important because: - `is_any_keyword()` is called from `advance()` on **every single token** - This is one of the hottest code paths in the entire parser ## Testing Added unit tests to verify that: - All keywords remain contiguous in the enum (`Await..=Yield`) - All numeric literals remain contiguous (`Decimal..=HexBigInt`) These tests will catch any future enum reordering that would break the optimization. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
9598a9e to
2b6a3b4
Compare
Summary
Replace multi-function calls and multiple enum variant checks with simple range checks, reducing assembly instructions in hot paths.
Changes
is_any_keyword()Before: Called 4 separate functions checking 70+ enum variants:
is_reserved_keyword()- 38 variantsis_contextual_keyword()- 39 variantsis_strict_mode_contextual_keyword()- 8 variantsis_future_reserved_keyword()- 7 variantsAfter: Single range check
Await..=Yieldsince all keywords are contiguous in the enumis_number()Before: Matched 11 separate enum variants
After: Single range check
Decimal..=HexBigIntsince numeric literals are contiguousAssembly Analysis
Before (with scattered checks)
5 instructions with complex constant loading
After (with range check)
4 instructions with simple arithmetic
Performance Impact
This is particularly important because:
is_any_keyword()is called fromadvance()on every single tokenTesting
Added unit tests to verify that:
Await..=Yield)Decimal..=HexBigInt)These tests will catch any future enum reordering that would break the optimization.
🤖 Generated with Claude Code