Skip to content

Commit

Permalink
perf(es/minifier): Parallelize handling of class members (#9900)
Browse files Browse the repository at this point in the history
**Description:**

These methods were missing and it makes the minification of some files needlessly slow.
  • Loading branch information
kdy1 authored Jan 19, 2025
1 parent 2d87b89 commit ed74839
Show file tree
Hide file tree
Showing 11 changed files with 262 additions and 203 deletions.
9 changes: 9 additions & 0 deletions .changeset/calm-frogs-search.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
swc_core: patch
swc_ecma_lints: patch
swc_ecma_transforms_base: patch
swc_ecma_transforms_optimization: patch
swc_ecma_minifier: patch
---

perf(es/minifier): Parallelize handling of class members
6 changes: 6 additions & 0 deletions crates/swc_ecma_lints/src/rules/const_assign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,12 @@ impl Visit for ConstAssign<'_> {
self.check(&Ident::from(n));
}

fn visit_class_members(&mut self, members: &[ClassMember]) {
self.maybe_par(cpu_count(), members, |v, member| {
member.visit_with(v);
});
}

fn visit_expr_or_spreads(&mut self, n: &[ExprOrSpread]) {
self.maybe_par(cpu_count(), n, |v, n| {
n.visit_with(v);
Expand Down
6 changes: 6 additions & 0 deletions crates/swc_ecma_lints/src/rules/no_dupe_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,12 @@ impl Visit for NoDupeArgs {
f.visit_children_with(self);
}

fn visit_class_members(&mut self, members: &[ClassMember]) {
self.maybe_par(cpu_count(), members, |v, member| {
member.visit_with(v);
});
}

fn visit_constructor(&mut self, f: &Constructor) {
check!(&f.params);

Expand Down
154 changes: 80 additions & 74 deletions crates/swc_ecma_minifier/src/compress/optimize/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -308,24 +308,6 @@ enum FinalizerMode {
impl VisitMut for Finalizer<'_> {
noop_visit_mut_type!();

fn visit_mut_callee(&mut self, e: &mut Callee) {
e.visit_mut_children_with(self);

if let Callee::Expr(e) = e {
self.check(e, FinalizerMode::Callee);
}
}

fn visit_mut_member_expr(&mut self, e: &mut MemberExpr) {
e.visit_mut_children_with(self);

if let MemberProp::Computed(ref mut prop) = e.prop {
if let Expr::Lit(Lit::Num(..)) = &*prop.expr {
self.check(&mut e.obj, FinalizerMode::MemberAccess);
}
}
}

fn visit_mut_bin_expr(&mut self, e: &mut BinExpr) {
e.visit_mut_children_with(self);

Expand All @@ -342,65 +324,17 @@ impl VisitMut for Finalizer<'_> {
}
}

fn visit_mut_var_declarators(&mut self, n: &mut Vec<VarDeclarator>) {
n.visit_mut_children_with(self);

n.retain(|v| !v.name.is_invalid());
}

fn visit_mut_var_declarator(&mut self, n: &mut VarDeclarator) {
n.visit_mut_children_with(self);

if n.init.is_none() {
if let Pat::Ident(i) = &n.name {
if self.vars_to_remove.contains(&i.to_id()) {
n.name.take();
}
}
}
}

fn visit_mut_opt_var_decl_or_expr(&mut self, n: &mut Option<VarDeclOrExpr>) {
n.visit_mut_children_with(self);

if let Some(VarDeclOrExpr::VarDecl(v)) = n {
if v.decls.is_empty() {
*n = None;
}
}
}

fn visit_mut_stmt(&mut self, n: &mut Stmt) {
n.visit_mut_children_with(self);
fn visit_mut_callee(&mut self, e: &mut Callee) {
e.visit_mut_children_with(self);

if let Stmt::Decl(Decl::Var(v)) = n {
if v.decls.is_empty() {
n.take();
}
if let Callee::Expr(e) = e {
self.check(e, FinalizerMode::Callee);
}
}

fn visit_mut_prop_or_spreads(&mut self, n: &mut Vec<PropOrSpread>) {
self.maybe_par(*HEAVY_TASK_PARALLELS, n, |v, n| {
n.visit_mut_with(v);
});
}

fn visit_mut_expr_or_spreads(&mut self, n: &mut Vec<ExprOrSpread>) {
self.maybe_par(*HEAVY_TASK_PARALLELS, n, |v, n| {
n.visit_mut_with(v);
});
}

fn visit_mut_opt_vec_expr_or_spreads(&mut self, n: &mut Vec<Option<ExprOrSpread>>) {
self.maybe_par(*HEAVY_TASK_PARALLELS, n, |v, n| {
n.visit_mut_with(v);
});
}

fn visit_mut_exprs(&mut self, n: &mut Vec<Box<Expr>>) {
self.maybe_par(*HEAVY_TASK_PARALLELS, n, |v, n| {
n.visit_mut_with(v);
fn visit_mut_class_members(&mut self, members: &mut Vec<ClassMember>) {
self.maybe_par(*HEAVY_TASK_PARALLELS, members, |v, member| {
member.visit_mut_with(v);
});
}

Expand Down Expand Up @@ -436,17 +370,89 @@ impl VisitMut for Finalizer<'_> {
n.visit_mut_children_with(self);
}

fn visit_mut_stmts(&mut self, n: &mut Vec<Stmt>) {
fn visit_mut_expr_or_spreads(&mut self, n: &mut Vec<ExprOrSpread>) {
self.maybe_par(*HEAVY_TASK_PARALLELS, n, |v, n| {
n.visit_mut_with(v);
});
}

fn visit_mut_exprs(&mut self, n: &mut Vec<Box<Expr>>) {
self.maybe_par(*HEAVY_TASK_PARALLELS, n, |v, n| {
n.visit_mut_with(v);
});
}

fn visit_mut_member_expr(&mut self, e: &mut MemberExpr) {
e.visit_mut_children_with(self);

if let MemberProp::Computed(ref mut prop) = e.prop {
if let Expr::Lit(Lit::Num(..)) = &*prop.expr {
self.check(&mut e.obj, FinalizerMode::MemberAccess);
}
}
}

fn visit_mut_module_items(&mut self, n: &mut Vec<ModuleItem>) {
self.maybe_par(*HEAVY_TASK_PARALLELS, n, |v, n| {
n.visit_mut_with(v);
});
}

fn visit_mut_opt_var_decl_or_expr(&mut self, n: &mut Option<VarDeclOrExpr>) {
n.visit_mut_children_with(self);

if let Some(VarDeclOrExpr::VarDecl(v)) = n {
if v.decls.is_empty() {
*n = None;
}
}
}

fn visit_mut_opt_vec_expr_or_spreads(&mut self, n: &mut Vec<Option<ExprOrSpread>>) {
self.maybe_par(*HEAVY_TASK_PARALLELS, n, |v, n| {
n.visit_mut_with(v);
});
}

fn visit_mut_prop_or_spreads(&mut self, n: &mut Vec<PropOrSpread>) {
self.maybe_par(*HEAVY_TASK_PARALLELS, n, |v, n| {
n.visit_mut_with(v);
});
}

fn visit_mut_stmt(&mut self, n: &mut Stmt) {
n.visit_mut_children_with(self);

if let Stmt::Decl(Decl::Var(v)) = n {
if v.decls.is_empty() {
n.take();
}
}
}

fn visit_mut_stmts(&mut self, n: &mut Vec<Stmt>) {
self.maybe_par(*HEAVY_TASK_PARALLELS, n, |v, n| {
n.visit_mut_with(v);
});
}

fn visit_mut_var_declarator(&mut self, n: &mut VarDeclarator) {
n.visit_mut_children_with(self);

if n.init.is_none() {
if let Pat::Ident(i) = &n.name {
if self.vars_to_remove.contains(&i.to_id()) {
n.name.take();
}
}
}
}

fn visit_mut_var_declarators(&mut self, n: &mut Vec<VarDeclarator>) {
n.visit_mut_children_with(self);

n.retain(|v| !v.name.is_invalid());
}
}

pub(crate) struct NormalMultiReplacer<'a> {
Expand Down
32 changes: 16 additions & 16 deletions crates/swc_ecma_minifier/src/compress/pure/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ impl Pure<'_> {
where
N: for<'aa> VisitMutWith<Pure<'aa>> + Send + Sync,
{
self.maybe_par(cpu_count() * 8, nodes, |v, node| {
self.maybe_par(cpu_count() * 2, nodes, |v, node| {
node.visit_mut_with(v);
});
}
Expand Down Expand Up @@ -243,20 +243,6 @@ impl VisitMut for Pure<'_> {
self.drop_arguments_of_symbol_call(e);
}

fn visit_mut_opt_call(&mut self, opt_call: &mut OptCall) {
{
let ctx = Ctx {
is_callee: true,
..self.ctx
};
opt_call.callee.visit_mut_with(&mut *self.with_ctx(ctx));
}

opt_call.args.visit_mut_with(self);

self.eval_spread_array(&mut opt_call.args);
}

fn visit_mut_class_member(&mut self, m: &mut ClassMember) {
m.visit_mut_children_with(self);

Expand All @@ -268,7 +254,7 @@ impl VisitMut for Pure<'_> {
}

fn visit_mut_class_members(&mut self, m: &mut Vec<ClassMember>) {
m.visit_mut_children_with(self);
self.visit_par(m);

m.retain(|m| {
if let ClassMember::Empty(..) = m {
Expand Down Expand Up @@ -673,6 +659,20 @@ impl VisitMut for Pure<'_> {
e.args.visit_mut_with(self);
}

fn visit_mut_opt_call(&mut self, opt_call: &mut OptCall) {
{
let ctx = Ctx {
is_callee: true,
..self.ctx
};
opt_call.callee.visit_mut_with(&mut *self.with_ctx(ctx));
}

opt_call.args.visit_mut_with(self);

self.eval_spread_array(&mut opt_call.args);
}

fn visit_mut_opt_var_decl_or_expr(&mut self, n: &mut Option<VarDeclOrExpr>) {
n.visit_mut_children_with(self);

Expand Down
50 changes: 28 additions & 22 deletions crates/swc_ecma_minifier/src/util/base54.rs
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,24 @@ impl Visit for CharFreqAnalyzer<'_> {

visit_obj_and_computed!();

fn visit_class_members(&mut self, members: &[ClassMember]) {
self.maybe_par(cpu_count(), members, |v, member| {
member.visit_with(v);
});
}

fn visit_expr_or_spreads(&mut self, n: &[ExprOrSpread]) {
self.maybe_par(cpu_count(), n, |v, n| {
n.visit_with(v);
});
}

fn visit_exprs(&mut self, exprs: &[Box<Expr>]) {
self.maybe_par(cpu_count(), exprs, |v, expr| {
expr.visit_with(v);
});
}

fn visit_ident(&mut self, i: &Ident) {
if i.ctxt == self.unresolved_ctxt && i.sym != "arguments" {
return;
Expand All @@ -339,31 +357,9 @@ impl Visit for CharFreqAnalyzer<'_> {
self.freq.scan(&i.sym, -1);
}

fn visit_prop_name(&mut self, n: &PropName) {
match n {
PropName::Ident(_) => {}
PropName::Str(_) => {}
PropName::Num(_) => {}
PropName::Computed(e) => e.visit_with(self),
PropName::BigInt(_) => {}
}
}

/// This is preserved anyway
fn visit_module_export_name(&mut self, _: &ModuleExportName) {}

fn visit_expr_or_spreads(&mut self, n: &[ExprOrSpread]) {
self.maybe_par(cpu_count(), n, |v, n| {
n.visit_with(v);
});
}

fn visit_exprs(&mut self, exprs: &[Box<Expr>]) {
self.maybe_par(cpu_count(), exprs, |v, expr| {
expr.visit_with(v);
});
}

fn visit_module_items(&mut self, items: &[ModuleItem]) {
self.maybe_par(cpu_count(), items, |v, item| {
item.visit_with(v);
Expand All @@ -376,6 +372,16 @@ impl Visit for CharFreqAnalyzer<'_> {
});
}

fn visit_prop_name(&mut self, n: &PropName) {
match n {
PropName::Ident(_) => {}
PropName::Str(_) => {}
PropName::Num(_) => {}
PropName::Computed(e) => e.visit_with(self),
PropName::BigInt(_) => {}
}
}

fn visit_prop_or_spreads(&mut self, n: &[PropOrSpread]) {
self.maybe_par(cpu_count(), n, |v, n| {
n.visit_with(v);
Expand Down
6 changes: 6 additions & 0 deletions crates/swc_ecma_transforms_base/src/rename/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -522,6 +522,12 @@ where
}
}

fn visit_mut_class_members(&mut self, members: &mut Vec<ClassMember>) {
self.maybe_par(cpu_count(), members, |v, member| {
member.visit_mut_with(v);
});
}

fn visit_mut_prop_or_spreads(&mut self, n: &mut Vec<PropOrSpread>) {
self.maybe_par(cpu_count() * 100, n, |v, n| {
n.visit_mut_with(v);
Expand Down
Loading

0 comments on commit ed74839

Please sign in to comment.