Skip to content

perf(cache): store canonical path as Box<Path> instead of PathBuf#1143

Merged
graphite-app[bot] merged 1 commit into
mainfrom
perf/cached-path-canonicalized-box
May 23, 2026
Merged

perf(cache): store canonical path as Box<Path> instead of PathBuf#1143
graphite-app[bot] merged 1 commit into
mainfrom
perf/cached-path-canonicalized-box

Conversation

@Boshen

@Boshen Boshen commented May 23, 2026

Copy link
Copy Markdown
Member

Summary

CachedPathImpl::canonicalized cached the canonical path as PathBuf even though it's set once and never mutated. PathBuf is Vec<u8>-sized (ptr + len + cap = 24 bytes); Box<Path> only needs ptr + len = 16 bytes. The capacity word was dead weight.

Switching the field type shrinks the OnceLock<(Weak<Self>, ...)> tuple from 40 to 32 bytes — saving 8 bytes per cached path entry. For a resolver session with 10k cached paths that's ~80 KB; with 100k it's ~800 KB.

The setter now clones the existing Box<Path> of the canonical entry instead of calling to_path_buf(), so we don't take a PathBuf detour either.

🤖 Generated with Claude Code

@codecov

codecov Bot commented May 23, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 66.66667% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 93.12%. Comparing base (9e6a648) to head (98617e3).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/cache/cache_impl.rs 66.66% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1143   +/-   ##
=======================================
  Coverage   93.12%   93.12%           
=======================================
  Files          21       21           
  Lines        4089     4089           
=======================================
  Hits         3808     3808           
  Misses        281      281           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@codspeed-hq

codspeed-hq Bot commented May 23, 2026

Copy link
Copy Markdown

Merging this PR will improve performance by 16.41%

⚠️ Different runtime environments detected

Some benchmarks with significant performance changes were compared across different runtime environments,
which may affect the accuracy of the results.

Open the report in CodSpeed to investigate

⚡ 6 improved benchmarks
❌ 1 regressed benchmark
✅ 6 untouched benchmarks
⏩ 5 skipped benchmarks1

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
complex_real 21.6 µs 22.4 µs -3.5%
resolver_memory[resolve from symlinks] 49.3 ms 35.7 ms +38.19%
resolver_memory[single-thread] 425.2 µs 384.3 µs +10.65%
resolver_real[multi-thread] 435 µs 391.4 µs +11.12%
resolver_real[resolve from symlinks] 48.9 ms 35.5 ms +37.85%
resolver_real[single-thread] 426.7 µs 380.4 µs +12.18%
resolver_memory[multi-thread] 445.4 µs 389.8 µs +14.25%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing perf/cached-path-canonicalized-box (98617e3) with main (22fafa2)2

Open in CodSpeed

Footnotes

  1. 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.

  2. No successful run was found on main (98617e3) 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.

@Boshen Boshen added the merge label May 23, 2026

Boshen commented May 23, 2026

Copy link
Copy Markdown
Member Author

Merge activity

)

## Summary

`CachedPathImpl::canonicalized` cached the canonical path as `PathBuf` even though it's set once and never mutated. `PathBuf` is `Vec<u8>`-sized (`ptr + len + cap` = 24 bytes); `Box<Path>` only needs `ptr + len` = 16 bytes. The capacity word was dead weight.

Switching the field type shrinks the `OnceLock<(Weak<Self>, ...)>` tuple from 40 to 32 bytes — saving **8 bytes per cached path entry**. For a resolver session with 10k cached paths that's ~80 KB; with 100k it's ~800 KB.

The setter now clones the existing `Box<Path>` of the canonical entry instead of calling `to_path_buf()`, so we don't take a PathBuf detour either.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
@graphite-app graphite-app Bot force-pushed the perf/cached-path-canonicalized-box branch from 39f4fac to 98617e3 Compare May 23, 2026 05:56
@graphite-app graphite-app Bot merged commit 98617e3 into main May 23, 2026
18 checks passed
@graphite-app graphite-app Bot removed the merge label May 23, 2026
@graphite-app graphite-app Bot deleted the perf/cached-path-canonicalized-box branch May 23, 2026 05:59
@oxc-guard oxc-guard Bot mentioned this pull request May 23, 2026
Boshen added a commit that referenced this pull request May 25, 2026
## 🤖 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>
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