Avatar for the oxc-project user
oxc-project
oxc-resolver
BlogDocsChangelog

Performance History

Latest Results

perf(resolve): skip redundant is_dir when reading a directory's package.json `get_package_json` routes through `find_package_json`, whose leading `while !is_dir(path)` walk only matters when `path` is not a directory. Three call sites already hold a directory β€” the `find_package_json_for_a_package` walk loop, the `node_modules` package lookup, and `load_package_exports` (each right after / inside an `is_dir` check) β€” yet route through that walk, re-checking `is_dir` on a path already known to be a directory. Add `get_package_json_of_dir`, which calls `find_package_json_impl` directly and shares the same "package.json lives directly in this dir" filter (`filter_own_package_json`); a `debug_assert!` enforces the directory precondition. For a directory the skipped `is_dir` returns true and records no dependency, so both the result and the recorded dependency set are identical (the exact-vector `dependencies.rs` contract test passes). `get_package_json` is left unchanged because one caller can pass a non-directory path. This removes redundant work in the package.json lookup path; the saving is within benchmark noise (the is_dir hit is a single cached atomic load).
perf/dedup-is-dir-package-json
8 hours ago
chore: release v11.22.0
release-plz-2026-06-18T23-48-37Z
10 hours ago
perf(tsconfig): reuse cached lstat to avoid redundant stat in get_tsconfig (#1238) ## Problem While tracing every `FileSystem` syscall during resolve, module resolution turned out to be redundancy-free (cold + warm), but **tsconfig loading double-stats every config file**. `Cache::get_tsconfig` classifies the config path with `fs.metadata` (a `stat`) to decide file-vs-dir, then canonicalizes the same path β€” which issues an `lstat`. Those populate different cache slots (`followed` vs `link`), so neither reuses the other. Every tsconfig in an `extends`/`references` graph was therefore both `stat`'d **and** `lstat`'d. ## Fix Classify via the cached `link_metadata` (`lstat`, the same slot canonicalization needs) and only fall back to `stat` when the path is actually a symlink: ```rust let cached_path = self.value(path); let meta = match cached_path.link_metadata(&self.fs) { Some(m) if m.is_symlink() => self.fs.metadata(path).ok(), other => other, }; ``` The later `canonicalize(&self.value(&tsconfig_path))` now reuses that cached `lstat` (same path β†’ same `Arc<CachedPathImpl>` via the path cache), removing one metadata syscall per config file on cold load. Symlink-following classification is preserved for all four cases (regular file/dir, symlinkβ†’file, symlinkβ†’dir, missing). This is a cold-only win (a tsconfig loads once per resolver), in the same spirit as the earlier lstat/stat-unification work. ## Measurements Traced over the tsconfig fixtures (cold load): | scenario | before | after | Ξ” | | --- | --- | --- | --- | | `extends-chain` (3 configs) | 21 syscalls | 18 | βˆ’14% | | `project-references` (6 configs) | 39 syscalls | 33 | βˆ’15% | The `stat` op is eliminated from tsconfig loading entirely. ## Verification - `cargo test --all-features` β€” 315 tests pass (77 tsconfig) - `cargo clippy --all-features` β€” clean - `cargo check --all-features --all-targets` β€” clean
main
10 hours ago
chore: release v11.22.0
release-plz-2026-06-18T23-48-37Z
11 hours ago
chore(bench): pin rayon thread count so parallel benches are deterministic (#1237) ## Problem The CodSpeed reports are flaky. The same benchmarks swing wildly on PRs that can't possibly affect them: | PR | Changed | Bogus CodSpeed swings | | --- | --- | --- | | #1232 | tsconfig glob only | `pm/npm-flat` **βˆ’7.3%**, `resolver_real[multi-thread]` βˆ’5.9%, `pm/yarn-isolated` **+12%** | | #1235 | 1-line `parent()` dedup | `pm/bun-flat` **+10%**, `pm/yarn-flat` +5.5%, `resolver_memory[multi-thread]` βˆ’5.4% | CodSpeed itself flags **"⚠️ Different runtime environments detected"** on these. ## Root cause The `pm/*` and `resolver_*[multi-thread]` benches fan resolution out across **`rayon` worker threads**, and nothing pins the thread count β€” so rayon uses each runner's detected core count, which **varies across GitHub `ubuntu-latest` runners**. Under CodSpeed's instrumentation (Valgrind serializes threads onto one core and counts instructions), a different pool size between the BASE and HEAD runs produces wildly different instruction totals. ## Fix Pin rayon's global pool to a **fixed 4 threads** at the start of each parallel bench (idempotent `build_global`). The thread count is now identical across machines and runs, so under Valgrind's deterministic scheduling the instrumented instruction count is deterministic β€” while the benches stay multi-threaded under local `cargo bench`. No `cfg`/feature split: the benches behave the same locally and under CodSpeed. Verified both `cargo bench --no-run` and `cargo bench --no-run --features codspeed` compile with no warnings.
main
11 hours ago

Latest Branches

CodSpeed Performance Gauge
+7%
perf(resolve): skip redundant is_dir when reading a directory's package.json#1239
8 hours ago
b51530c
perf/dedup-is-dir-package-json
CodSpeed Performance Gauge
+7%
chore: release v11.22.0#1228
10 hours ago
9e08fb8
release-plz-2026-06-18T23-48-37Z
CodSpeed Performance Gauge
-6%
perf(tsconfig): reuse cached lstat to avoid redundant stat in get_tsconfig#1238
10 hours ago
ae10555
perf/tsconfig-cached-lstat
Β© 2026 CodSpeed Technology
Home Terms Privacy Docs