perf(alias): fast-reject alias entries by cached first byte#1142
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #1142 +/- ##
==========================================
+ Coverage 93.11% 93.12% +0.01%
==========================================
Files 21 21
Lines 4082 4089 +7
==========================================
+ Hits 3801 3808 +7
Misses 281 281 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Merging this PR will improve performance by 15.89%
|
| Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|
| ❌ | complex_real |
21.6 µs | 22.6 µs | -4.53% |
| ⚡ | resolver_real[multi-thread] |
435 µs | 402.5 µs | +8.08% |
| ⚡ | resolver_real[resolve from symlinks] |
48.9 ms | 35.4 ms | +38.13% |
| ⚡ | resolver_memory[multi-thread] |
445.4 µs | 386.7 µs | +15.16% |
| ⚡ | resolver_real[single-thread] |
426.7 µs | 380.8 µs | +12.06% |
| ⚡ | resolver_memory[resolve from symlinks] |
49.3 ms | 35.6 ms | +38.52% |
| ⚡ | resolver_memory[single-thread] |
425.2 µs | 385.8 µs | +10.23% |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing perf/alias-first-byte-filter (9e6a648) with main (22fafa2)2
Footnotes
-
5 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩
-
No successful run was found on
main(9e6a648) during the generation of this report, so 22fafa2 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report. ↩
7b7abd9 to
55db42a
Compare
Merge activity
|
## Summary `load_alias` iterates every alias entry on every resolve, even when none can possibly match the current specifier. Each iteration dispatches on `match_kind` and calls `strip_prefix`/equality on the alias key. For configurations with many entries (real-world bundler configs commonly have 20+ aliases), most of this work is on entries whose first byte already disagrees with the specifier's first byte. This PR caches the first byte of the alias key (or wildcard prefix) at `compile_alias` time and skips non-matching entries before dispatching into the match-kind branch. Wildcard entries with an empty prefix store `None` and continue to be evaluated for every specifier (they can match anything). ## Measurement Memory-FS benches, `cargo bench -- --baseline main`: | Benchmark | Before | After | Δ | | --- | --- | --- | --- | | `resolver_memory/single-thread` | ~50 µs | ~40.5 µs | **−19%** | | `resolver_memory/find tsconfig` | ~870 ns | ~565 ns | **−35%** | 🤖 Generated with [Claude Code](https://claude.com/claude-code)
55db42a to
9e6a648
Compare
## 🤖 New release * `oxc_resolver`: 11.19.1 -> 11.19.2 * `oxc_resolver_napi`: 11.19.1 -> 11.19.2 <details><summary><i><b>Changelog</b></i></summary><p> ## `oxc_resolver` <blockquote> ## [11.19.2](v11.19.1...v11.19.2) - 2026-05-25 ### <!-- 1 -->🐛 Bug Fixes - *(tsconfig)* apply later-wins semantics for extends array ([#1156](#1156)) (by @Boshen) - *(tsconfig)* walk past a tsconfig that doesn't claim the file ([#1154](#1154)) (by @Boshen) - *(tsconfig)* let project references take priority over their parent ([#1151](#1151)) (by @Boshen) - *(tsconfig)* resolve `rootDirs` against the config that declared them ([#1150](#1150)) (by @Boshen) - *(tsconfig)* resolve `baseUrl` / `paths` against the canonical tsconfig path ([#1148](#1148)) (by @Boshen) - strip query fragments when calling `find_tsconfig` ([#1147](#1147)) (by @Boshen) - avoid panic in resolve_file for parentless paths ([#1053](#1053)) (by @Boshen) - *(dts)* strip ./ prefix from package entry when matching typesVersions ([#1051](#1051)) (by @Boshen) - *(dts)* expand Declaration to TypeScript|Declaration for package entry resolution ([#1050](#1050)) (by @Boshen) - *(dts)* prefer declaration extensions over JS in exports-resolved paths ([#1047](#1047)) (by @Boshen) - avoid wasm/wasi dead-code lint in NodePath ([#1043](#1043)) (by @Boshen) - *(napi)* replace panics with error returns to prevent WASM traps ([#1055](#1055)) (by @Boshen) ### <!-- 2 -->🚜 Refactor - remove clear_cache test that dynamically creates fixtures (by @Boshen) - move resolve and misc fixtures into fixtures/integration (by @Boshen) - replace ignored doctest with link to example (by @Boshen) - consolidate fixture directories for better test file mapping (by @Boshen) - replace `url` crate with `percent-encoding` ([#1065](#1065)) (by @Boshen) ### <!-- 4 -->⚡ Performance - *(cache)* pack CachedPathImpl::meta into a CachedMeta byte ([#1144](#1144)) (by @Boshen) - *(cache)* store canonical path as Box<Path> instead of PathBuf ([#1143](#1143)) (by @Boshen) - *(alias)* fast-reject alias entries by cached first byte ([#1142](#1142)) (by @Boshen) ### <!-- 6 -->🧪 Testing - *(tsconfig)* port lookup scenarios from typescript-go ([#1155](#1155)) (by @Boshen) - add 28 tests to improve coverage (92% → 93%) ([#1082](#1082)) (by @Boshen) ### Contributors * @Boshen * @renovate[bot] </blockquote> </p></details> --- This PR was generated with [release-plz](https://github.com/release-plz/release-plz/). Co-authored-by: oxc-guard[bot] <276638029+oxc-guard[bot]@users.noreply.github.com>
Summary
load_aliasiterates every alias entry on every resolve, even when none can possibly match the current specifier. Each iteration dispatches onmatch_kindand callsstrip_prefix/equality on the alias key. For configurations with many entries (real-world bundler configs commonly have 20+ aliases), most of this work is on entries whose first byte already disagrees with the specifier's first byte.This PR caches the first byte of the alias key (or wildcard prefix) at
compile_aliastime and skips non-matching entries before dispatching into the match-kind branch. Wildcard entries with an empty prefix storeNoneand continue to be evaluated for every specifier (they can match anything).Measurement
Memory-FS benches,
cargo bench -- --baseline main:resolver_memory/single-threadresolver_memory/find tsconfig🤖 Generated with Claude Code