Skip to content

Commit 4ded22b

Browse files
committed
perf(codegen): reduce allocations in SourcemapBuilder (#13677)
Follow-on after #13670. That PR made 2 changes: 1. Pre-allocating capacity in `columns` `Vec`. 2. `mem::take`-ing `columns` for each line, rather than re-using it. In my opinion, the 1st change is good, but the 2nd is not. Revert the usage of `mem::take`, and add a comment explaining why the `.clone()` is not as bad as it looks! Before this PR: `columns` will likely have spare capacity, so `mem::take(&mut columns).into_boxed_slice()` will perform a reallocation to drop the excess capacity, and then `columns.reserve(256)` performs a 2nd allocation. Approach after this PR: 1. `columns.clone().into_boxed_slice()` performs 1 allocation, and copies the data from `columns` into this new allocation. `columns.clear()` does not perform any reallocation, and is a very cheap operation. 2. `columns` `Vec` is reused over and over, and will grow adaptively depending on how heavy the file's use of unicode chars is, rather than always going back to estimated max capacity of 256. Benchmarks show a very small positive difference.
1 parent 239d4cb commit 4ded22b

File tree

1 file changed

+9
-5
lines changed

1 file changed

+9
-5
lines changed

crates/oxc_codegen/src/sourcemap_builder.rs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -389,14 +389,18 @@ impl<'a> SourcemapBuilder<'a> {
389389
// `chunk_byte_offset` is now the offset of *end* of the line break.
390390
line_byte_offset += chunk_byte_offset;
391391

392-
// Record column offsets
393-
// Use mem::take to avoid clone - moves columns out and replaces with empty Vec
392+
// Record column offsets.
393+
// `columns.clone().into_boxed_slice()` does perform an allocation,
394+
// but only one - `Vec::clone` produces a `Vec` with `capacity == len`,
395+
// so `Vec::into_boxed_slice` just drops the `capacity` field,
396+
// and does not need to reallocate again.
397+
// `columns` is reused for next line, and will grow adaptively depending on
398+
// how heavily the file uses unicode chars.
394399
column_offsets.push(ColumnOffsets {
395400
byte_offset_to_first: byte_offset_from_line_start,
396-
columns: std::mem::take(&mut columns).into_boxed_slice(),
401+
columns: columns.clone().into_boxed_slice(),
397402
});
398-
// Reserve capacity for next line to avoid reallocation
399-
columns.reserve(256);
403+
columns.clear();
400404

401405
// Revert back to outer loop for next line
402406
continue 'lines;

0 commit comments

Comments
 (0)