Skip to content

Commit 30a2b0f

Browse files
committed
perf(minifier): use atom_from_strs_array for template literal concat (#20386)
## Summary - Replace 4 instances of heap `String` concatenation with `ctx.ast.atom_from_strs_array()` - Avoids intermediate heap allocations by concatenating directly into the arena allocator - Affects template literal merging and expression inlining into quasis 🤖 Generated with [Claude Code](https://claude.com/claude-code)
1 parent ed5a7fb commit 30a2b0f

File tree

2 files changed

+14
-13
lines changed

2 files changed

+14
-13
lines changed

crates/oxc_minifier/src/peephole/fold_constants.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -411,12 +411,14 @@ impl<'a> PeepholeOptimizations {
411411
.quasis
412412
.first_mut()
413413
.expect("template literal must have at least one quasi");
414-
let new_raw = left_last_quasi.value.raw.to_string() + &right_first_quasi.value.raw;
415-
left_last_quasi.value.raw = ctx.ast.atom(&new_raw);
414+
left_last_quasi.value.raw = ctx.ast.atom_from_strs_array([
415+
left_last_quasi.value.raw.as_str(),
416+
right_first_quasi.value.raw.as_str(),
417+
]);
416418
let new_cooked = if let (Some(cooked1), Some(cooked2)) =
417419
(left_last_quasi.value.cooked, right_first_quasi.value.cooked)
418420
{
419-
Some(ctx.ast.atom(&(cooked1.into_string() + cooked2.as_str())))
421+
Some(ctx.ast.atom_from_strs_array([cooked1.as_str(), cooked2.as_str()]))
420422
} else {
421423
None
422424
};
@@ -744,16 +746,15 @@ impl<'a> PeepholeOptimizations {
744746
let idx = idx - i;
745747
let next_quasi = (idx + 1 < t.quasis.len()).then(|| t.quasis.remove(idx + 1));
746748
let quasi = &mut t.quasis[idx];
747-
let new_raw = quasi.value.raw.into_string()
748-
+ &Self::escape_string_for_template_literal(&str)
749-
+ next_quasi.as_ref().map(|q| q.value.raw.as_str()).unwrap_or_default();
750-
quasi.value.raw = ctx.ast.atom(&new_raw);
749+
let escaped = Self::escape_string_for_template_literal(&str);
750+
let next_raw = next_quasi.as_ref().map(|q| q.value.raw.as_str()).unwrap_or_default();
751+
quasi.value.raw =
752+
ctx.ast.atom_from_strs_array([quasi.value.raw.as_str(), &escaped, next_raw]);
751753
let new_cooked = if let (Some(cooked1), Some(cooked2)) =
752754
(quasi.value.cooked, next_quasi.as_ref().map(|q| q.value.cooked))
753755
{
754-
let v =
755-
cooked1.into_string() + &str + cooked2.map(|c| c.as_str()).unwrap_or_default();
756-
Some(ctx.ast.atom(&v))
756+
let cooked2_str = cooked2.map(|c| c.as_str()).unwrap_or_default();
757+
Some(ctx.ast.atom_from_strs_array([cooked1.as_str(), &str, cooked2_str]))
757758
} else {
758759
None
759760
};

tasks/track_memory_allocations/allocs_minifier.snap

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ File | File size || Sys allocs | Sys reallocs |
22
-------------------------------------------------------------------------------------------------------------------------------------------
33
checker.ts | 2.92 MB || 329 | 37 || 152600 | 28244
44

5-
cal.com.tsx | 1.06 MB || 20245 | 52 || 37141 | 4583
5+
cal.com.tsx | 1.06 MB || 20239 | 46 || 37141 | 4583
66

77
RadixUIAdoptionSection.jsx | 2.52 kB || 34 | 6 || 30 | 6
88

9-
pdf.mjs | 567.30 kB || 3995 | 417 || 47464 | 7734
9+
pdf.mjs | 567.30 kB || 3993 | 417 || 47464 | 7734
1010

11-
antd.js | 6.69 MB || 7755 | 1661 || 331638 | 69344
11+
antd.js | 6.69 MB || 7751 | 1657 || 331638 | 69344
1212

1313
binder.ts | 193.08 kB || 78 | 23 || 7075 | 824
1414

0 commit comments

Comments
 (0)