Skip to content

Commit 2b6ee67

Browse files
committed
perf(semantic): pre-reserve unresolved_references using Stats::references
The unresolved_references Vec grows from 0 with default doubling, requiring ~13 reallocations to reach the typical ~5k references on a moderately-sized TypeScript file. Stats already knows the count up-front (or computes it in Stats::count); pre-reserving eliminates the growth reallocations. Benchmark (cargo bench --bench semantic): RadixUI.jsx (3KB JSX): 3.155 µs -> 3.051 µs (-3.3%) react.development.js: 136.47 µs -> 134.93 µs (-1.1%) cal.com.tsx (1MB TSX): 2.7414 ms -> 2.7055 ms (-1.3%) binder.ts (193KB TS): 314.90 µs -> 312.15 µs (-0.9%) All intervals non-overlapping on Criterion.
1 parent 180aa9f commit 2b6ee67

2 files changed

Lines changed: 8 additions & 0 deletions

File tree

crates/oxc_semantic/src/builder.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,7 @@ impl<'a> SemanticBuilder<'a> {
323323
stats.references as usize,
324324
stats.scopes as usize,
325325
);
326+
self.unresolved_references.reserve(stats.references as usize);
326327

327328
// Visit AST to generate scopes tree etc
328329
self.visit_program(program);

crates/oxc_semantic/src/unresolved_stack.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,13 @@ impl<'a> UnresolvedReferences<'a> {
1616
Self { references: Vec::new() }
1717
}
1818

19+
/// Reserve capacity for at least `additional` more references.
20+
/// Avoids growth reallocations when the expected count is known up-front.
21+
#[inline]
22+
pub(crate) fn reserve(&mut self, additional: usize) {
23+
self.references.reserve(additional);
24+
}
25+
1926
/// Push an unresolved reference to the flat list.
2027
#[inline]
2128
pub(crate) fn push(&mut self, name: Ident<'a>, reference_id: ReferenceId) {

0 commit comments

Comments
 (0)