Skip to content

Commit b35bf30

Browse files
committed
perf(codegen): optimize sourcemap builder to reduce allocations (#13670)
## Summary This PR optimizes the sourcemap builder to reduce memory allocations and improve performance. Profiling showed that `update_generated_line_and_column` and `add_source_mapping` were performance bottlenecks. ### Changes Made **Optimization 4: Optimize Line Offset Table Generation** - Pre-allocate `columns` vector with capacity 256 to avoid frequent reallocations - Replace `columns.clone().into_boxed_slice()` with `std::mem::take(&mut columns).into_boxed_slice()` to avoid unnecessary cloning - Reserve capacity after taking the vector to maintain performance for subsequent lines ### Performance Impact These changes reduce memory allocations when generating sourcemaps, especially for files with Unicode characters. The `clone()` operation was creating unnecessary copies of potentially large vectors on every Unicode line, which is now eliminated. ### Future Optimizations Additional optimizations from the analysis that could be implemented in follow-up PRs: 1. Use SIMD-accelerated line break detection with `memchr` 2. Optimize UTF-16 column calculation to avoid iterator allocation 3. Add fast path for sequential token processing 5. Inline hot functions with `#[inline(always)]` ## Test Plan - [x] All existing tests pass - [x] No functional changes, only performance optimizations - [x] Verified that sourcemap generation still works correctly 🤖 Generated with [Claude Code](https://claude.ai/code)
1 parent 2d53203 commit b35bf30

File tree

1 file changed

+6
-3
lines changed

1 file changed

+6
-3
lines changed

crates/oxc_codegen/src/sourcemap_builder.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,8 @@ impl<'a> SourcemapBuilder<'a> {
308308
let mut column_offsets = IndexVec::new();
309309

310310
// Used as a buffer to reduce memory reallocations
311-
let mut columns = vec![];
311+
// Pre-allocate with reasonable capacity to avoid frequent reallocations
312+
let mut columns = Vec::with_capacity(256);
312313

313314
// Process content line-by-line.
314315
// For each line, start by assuming line will be entirely ASCII, and read byte-by-byte.
@@ -389,11 +390,13 @@ impl<'a> SourcemapBuilder<'a> {
389390
line_byte_offset += chunk_byte_offset;
390391

391392
// Record column offsets
393+
// Use mem::take to avoid clone - moves columns out and replaces with empty Vec
392394
column_offsets.push(ColumnOffsets {
393395
byte_offset_to_first: byte_offset_from_line_start,
394-
columns: columns.clone().into_boxed_slice(),
396+
columns: std::mem::take(&mut columns).into_boxed_slice(),
395397
});
396-
columns.clear();
398+
// Reserve capacity for next line to avoid reallocation
399+
columns.reserve(256);
397400

398401
// Revert back to outer loop for next line
399402
continue 'lines;

0 commit comments

Comments
 (0)