Skip to content

Commit d074bca

Browse files
authored
perf(es/utils): Make IdentUsageFinder parallel (#10444)
**Related issue:** - Closes #9928
1 parent 8e4b6ce commit d074bca

File tree

1 file changed

+166
-0
lines changed
  • crates/swc_ecma_utils/src

1 file changed

+166
-0
lines changed

crates/swc_ecma_utils/src/lib.rs

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ pub extern crate swc_ecma_ast;
1515
use std::{borrow::Cow, hash::Hash, num::FpCategory, ops::Add};
1616

1717
use number::ToJsString;
18+
use once_cell::sync::Lazy;
19+
use parallel::{Parallel, ParallelExt};
1820
use rustc_hash::{FxHashMap, FxHashSet};
1921
use swc_atoms::Atom;
2022
use swc_common::{util::take::Take, Mark, Span, Spanned, SyntaxContext, DUMMY_SP};
@@ -60,6 +62,9 @@ pub struct ThisVisitor {
6062
found: bool,
6163
}
6264

65+
pub(crate) static CPU_COUNT: Lazy<usize> = Lazy::new(num_cpus::get);
66+
pub(crate) static LIGHT_TASK_PARALLELS: Lazy<usize> = Lazy::new(|| *CPU_COUNT * 100);
67+
6368
impl Visit for ThisVisitor {
6469
noop_visit_type!();
6570

@@ -1651,6 +1656,19 @@ pub struct IdentUsageFinder<'a> {
16511656
found: bool,
16521657
}
16531658

1659+
impl Parallel for IdentUsageFinder<'_> {
1660+
fn create(&self) -> Self {
1661+
Self {
1662+
ident: self.ident,
1663+
found: self.found,
1664+
}
1665+
}
1666+
1667+
fn merge(&mut self, other: Self) {
1668+
self.found = self.found || other.found;
1669+
}
1670+
}
1671+
16541672
impl Visit for IdentUsageFinder<'_> {
16551673
noop_visit_type!();
16561674

@@ -1661,6 +1679,50 @@ impl Visit for IdentUsageFinder<'_> {
16611679
self.found = true;
16621680
}
16631681
}
1682+
1683+
fn visit_class_members(&mut self, n: &[ClassMember]) {
1684+
self.maybe_par(*LIGHT_TASK_PARALLELS, n, |v, item| {
1685+
item.visit_with(v);
1686+
});
1687+
}
1688+
1689+
fn visit_expr_or_spreads(&mut self, n: &[ExprOrSpread]) {
1690+
self.maybe_par(*LIGHT_TASK_PARALLELS, n, |v, item| {
1691+
item.visit_with(v);
1692+
});
1693+
}
1694+
1695+
fn visit_exprs(&mut self, exprs: &[Box<Expr>]) {
1696+
self.maybe_par(*LIGHT_TASK_PARALLELS, exprs, |v, expr| {
1697+
expr.visit_with(v);
1698+
});
1699+
}
1700+
1701+
fn visit_module_items(&mut self, n: &[ModuleItem]) {
1702+
self.maybe_par(*LIGHT_TASK_PARALLELS, n, |v, item| {
1703+
item.visit_with(v);
1704+
});
1705+
}
1706+
1707+
fn visit_opt_vec_expr_or_spreads(&mut self, n: &[Option<ExprOrSpread>]) {
1708+
self.maybe_par(*LIGHT_TASK_PARALLELS, n, |v, item| {
1709+
if let Some(e) = item {
1710+
e.visit_with(v);
1711+
}
1712+
});
1713+
}
1714+
1715+
fn visit_stmts(&mut self, stmts: &[Stmt]) {
1716+
self.maybe_par(*LIGHT_TASK_PARALLELS, stmts, |v, stmt| {
1717+
stmt.visit_with(v);
1718+
});
1719+
}
1720+
1721+
fn visit_var_declarators(&mut self, n: &[VarDeclarator]) {
1722+
self.maybe_par(*LIGHT_TASK_PARALLELS, n, |v, item| {
1723+
item.visit_with(v);
1724+
});
1725+
}
16641726
}
16651727

16661728
impl<'a> IdentUsageFinder<'a> {
@@ -3549,3 +3611,107 @@ mod tests {
35493611
assert!(has_top_level_await("export default await 1;"));
35503612
}
35513613
}
3614+
3615+
#[cfg(test)]
3616+
mod ident_usage_finder_parallel_tests {
3617+
use swc_atoms::Atom;
3618+
use swc_common::SyntaxContext;
3619+
use swc_ecma_ast::*;
3620+
3621+
use super::*;
3622+
3623+
fn make_id(name: &str) -> Id {
3624+
(Atom::from(name), SyntaxContext::empty())
3625+
}
3626+
3627+
#[test]
3628+
fn test_visit_class_members() {
3629+
let id = make_id("foo");
3630+
let member = ClassMember::ClassProp(ClassProp {
3631+
key: PropName::Ident(quote_ident!("foo")),
3632+
value: Some(Box::new(Expr::Ident(quote_ident!("foo").into()))),
3633+
..Default::default()
3634+
});
3635+
let found = IdentUsageFinder::find(&id, &vec![member.clone()]);
3636+
assert!(found);
3637+
let not_found = IdentUsageFinder::find(&make_id("bar"), &vec![member]);
3638+
assert!(!not_found);
3639+
}
3640+
3641+
#[test]
3642+
fn test_visit_expr_or_spreads() {
3643+
let id = make_id("foo");
3644+
let expr = ExprOrSpread {
3645+
spread: None,
3646+
expr: Box::new(Expr::Ident(quote_ident!("foo").into())),
3647+
};
3648+
let found = IdentUsageFinder::find(&id, &vec![expr.clone()]);
3649+
assert!(found);
3650+
let not_found = IdentUsageFinder::find(&make_id("bar"), &vec![expr]);
3651+
assert!(!not_found);
3652+
}
3653+
3654+
#[test]
3655+
fn test_visit_module_items() {
3656+
let id = make_id("foo");
3657+
let item = ModuleItem::Stmt(Stmt::Expr(ExprStmt {
3658+
span: DUMMY_SP,
3659+
expr: Box::new(Expr::Ident(quote_ident!("foo").into())),
3660+
}));
3661+
let found = IdentUsageFinder::find(&id, &vec![item.clone()]);
3662+
assert!(found);
3663+
let not_found = IdentUsageFinder::find(&make_id("bar"), &vec![item]);
3664+
assert!(!not_found);
3665+
}
3666+
3667+
#[test]
3668+
fn test_visit_stmts() {
3669+
let id = make_id("foo");
3670+
let stmt = Stmt::Expr(ExprStmt {
3671+
span: DUMMY_SP,
3672+
expr: Box::new(Expr::Ident(quote_ident!("foo").into())),
3673+
});
3674+
let found = IdentUsageFinder::find(&id, &vec![stmt.clone()]);
3675+
assert!(found);
3676+
let not_found = IdentUsageFinder::find(&make_id("bar"), &vec![stmt]);
3677+
assert!(!not_found);
3678+
}
3679+
3680+
#[test]
3681+
fn test_visit_opt_vec_expr_or_spreads() {
3682+
let id = make_id("foo");
3683+
let expr = Some(ExprOrSpread {
3684+
spread: None,
3685+
expr: Box::new(Expr::Ident(quote_ident!("foo").into())),
3686+
});
3687+
let found = IdentUsageFinder::find(&id, &vec![expr.clone()]);
3688+
assert!(found);
3689+
let not_found = IdentUsageFinder::find(&make_id("bar"), &vec![expr]);
3690+
assert!(!not_found);
3691+
}
3692+
3693+
#[test]
3694+
fn test_visit_var_declarators() {
3695+
let id = make_id("foo");
3696+
let decl = VarDeclarator {
3697+
span: DUMMY_SP,
3698+
name: Pat::Ident(quote_ident!("foo").into()),
3699+
init: None,
3700+
definite: false,
3701+
};
3702+
let found = IdentUsageFinder::find(&id, &vec![decl.clone()]);
3703+
assert!(found);
3704+
let not_found = IdentUsageFinder::find(&make_id("bar"), &vec![decl]);
3705+
assert!(!not_found);
3706+
}
3707+
3708+
#[test]
3709+
fn test_visit_exprs() {
3710+
let id = make_id("foo");
3711+
let expr = Box::new(Expr::Ident(quote_ident!("foo").into()));
3712+
let found = IdentUsageFinder::find(&id, &vec![expr.clone()]);
3713+
assert!(found);
3714+
let not_found = IdentUsageFinder::find(&make_id("bar"), &vec![expr]);
3715+
assert!(!not_found);
3716+
}
3717+
}

0 commit comments

Comments
 (0)