next.js
9a4e4e7f - trace-server: shrink_to_fit LazySortedVec after sorting (#93361)

Commit
109 days ago
trace-server: shrink_to_fit LazySortedVec after sorting (#93361) ### What? In `turbopack-trace-server`, call `shrink_to_fit` on the inner storage of `LazySortedVec<T>` immediately after the one-shot sort that runs the first time the value is dereferenced. ### Why? `LazySortedVec` is built as a write-only `SmallVec<[T; 1]>` during trace ingestion (every `push` resets the inner `Once` so subsequent reads will resort), and is then "frozen" the first time it's `Deref`'d: the `Once::call_once` closure runs `sort()` once and the slice is handed out unchanged for the rest of the program's lifetime. Because the `SmallVec` grew via repeated `push`es, its capacity is typically a power-of-two well above its final length. After the first read, that overhead is dead memory we keep until the trace-server process exits. For traces with many spans, this adds up across all the `LazySortedVec`s on each span (e.g. the per-span event lists feeding the bottom-up / aggregated views), so the resident set of an idle trace-server is meaningfully larger than necessary. Since the `Once` guarantees the vector is never mutated again after the closure runs, the post-sort moment is the natural and only safe place to release that excess capacity. ### How? In the `Deref for LazySortedVec<T> where T: Ord` impl in `turbopack/crates/turbopack-trace-server/src/lazy_sorted_vec.rs`, the `once.call_once` closure now: 1. Reborrows the inner storage through the existing `UnsafeCell` pointer. 2. Calls `sort()` (unchanged behavior). 3. Calls `shrink_to_fit()` on the same `SmallVec`. The existing safety invariant — that the `&mut` reborrow inside `call_once` is exclusive because `Deref` is the only code path that touches the inner cell without a `&mut self`, and `Once` guarantees the closure runs at most once before any reader observes the slice — covers `shrink_to_fit` for free; it's just another exclusive mutation in the same scope as the sort. The `Deref` return path is unchanged: callers still receive a `&[T]` over the now-sorted, now-fitted backing storage. No public API change. No behavior change for callers. No new dependencies. ### Verification - `cargo build -p turbopack-trace-server` - `cargo clippy -p turbopack-trace-server` - `cargo fmt` No new tests: this is a pure memory-footprint optimization on a path that is already exercised by every existing read of a `LazySortedVec`. <!-- NEXT_JS_LLM_PR --> Co-authored-by: v-work-app[bot] <262237222+v-work-app[bot]@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Tobias Koppers <sokra@users.noreply.github.com>
Author
Parents
Loading