mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
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:
1 parent
7bb6b6235a
commit
fe1d367343
1 file changed
+87
-43
@@ -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']');
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user