perf(codegen): remove branches from loops printing arrays (#27840)

Perf optimization.

The loops for printing arrays (`ArrayExpression`, `ArrayPattern`, `ArrayAssignmentTarget`) contained multiple branches on each turn of the loop that prints the array elements. Move that logic out of the loops, so it executes once per array, instead of once per array element.
This commit is contained in:
overlookmotel committed 2026-10-16 20:20:21 +00:00
1 parent 7bb6b6235a
commit fe1d367343
1 file changed
+87 -43
+87 -43
View File
@@ -1669,32 +1669,54 @@ impl Gen for SpreadElement<'_> {
impl Gen for ArrayExpression<'_> {
fn r#gen(&self, p: &mut Codegen, ctx: Context) {
let is_multi_line = self.elements.len() > 2;
p.add_source_mapping(self.span);
p.print_ascii_byte(b'[');
if is_multi_line {
p.indent();
}
for (i, item) in self.elements.iter().enumerate() {
if i != 0 {
p.print_comma();
}
if is_multi_line {
if let Some((first, others)) = self.elements.split_first() {
let mut item = first;
if self.elements.len() > 2 {
// 3 or more elements, each on its own line
p.indent();
p.print_soft_newline();
p.print_indent();
} else if i != 0 {
p.print_soft_space();
}
item.print(p, ctx);
if i == self.elements.len() - 1 && matches!(item, ArrayExpressionElement::Elision(_)) {
p.print_comma();
item.print(p, ctx);
for item_ref in others {
item = item_ref;
p.print_comma();
p.print_soft_newline();
p.print_indent();
item.print(p, ctx);
}
if matches!(item, ArrayExpressionElement::Elision(_)) {
p.print_comma();
}
p.print_soft_newline();
p.dedent();
p.print_indent();
} else {
// 1 or 2 elements, on one line
item.print(p, ctx);
if let Some(item_ref) = others.first() {
item = item_ref;
p.print_comma();
p.print_soft_space();
item.print(p, ctx);
}
if matches!(item, ArrayExpressionElement::Elision(_)) {
p.print_comma();
}
}
}
if is_multi_line {
p.print_soft_newline();
p.dedent();
p.print_indent();
}
p.add_source_mapping_end(self.span);
p.print_ascii_byte(b']');
}
@@ -2160,24 +2182,35 @@ impl Gen for ArrayAssignmentTarget<'_> {
fn r#gen(&self, p: &mut Codegen, ctx: Context) {
p.add_source_mapping(self.span);
p.print_ascii_byte(b'[');
for (i, item) in self.elements.iter().enumerate() {
if i != 0 {
p.print_comma();
p.print_soft_space();
}
if let Some((first, others)) = self.elements.split_first() {
let mut item = first;
if let Some(item) = item {
item.print(p, ctx);
}
if i == self.elements.len() - 1 && (item.is_none() || self.rest.is_some()) {
for item_ref in others {
item = item_ref;
p.print_comma();
p.print_soft_space();
if let Some(item) = item {
item.print(p, ctx);
}
}
if let Some(rest) = &self.rest {
p.print_comma();
p.print_soft_space();
rest.print(p, ctx);
} else if item.is_none() {
p.print_comma();
}
} else if let Some(rest) = &self.rest {
rest.print(p, ctx);
}
if let Some(target) = &self.rest {
if !self.elements.is_empty() {
p.print_soft_space();
}
target.print(p, ctx);
}
p.print_ascii_byte(b']');
}
}
@@ -3206,24 +3239,35 @@ impl Gen for ArrayPattern<'_> {
fn r#gen(&self, p: &mut Codegen, ctx: Context) {
p.add_source_mapping(self.span);
p.print_ascii_byte(b'[');
for (index, item) in self.elements.iter().enumerate() {
if index != 0 {
p.print_comma();
p.print_soft_space();
}
if let Some((first, others)) = self.elements.split_first() {
let mut item = first;
if let Some(item) = item {
item.print(p, ctx);
}
if index == self.elements.len() - 1 && (item.is_none() || self.rest.is_some()) {
for item_ref in others {
item = item_ref;
p.print_comma();
p.print_soft_space();
if let Some(item) = item {
item.print(p, ctx);
}
}
if let Some(rest) = &self.rest {
p.print_comma();
p.print_soft_space();
rest.print(p, ctx);
} else if item.is_none() {
p.print_comma();
}
}
if let Some(rest) = &self.rest {
if !self.elements.is_empty() {
p.print_soft_space();
}
} else if let Some(rest) = &self.rest {
rest.print(p, ctx);
}
p.print_ascii_byte(b']');
}
}