Skip to content

Commit

Permalink
feat(es/utils): Add indexed API to the parallel helper (#6149)
Browse files Browse the repository at this point in the history
  • Loading branch information
kdy1 committed Oct 14, 2022
1 parent 8f349f8 commit 6a42e51
Showing 1 changed file with 38 additions and 13 deletions.
51 changes: 38 additions & 13 deletions crates/swc_ecma_utils/src/parallel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,13 @@ pub trait Parallel: swc_common::sync::Send + swc_common::sync::Sync {
#[cfg(feature = "concurrent")]
#[allow(clippy::len_without_is_empty)]
pub trait Items:
rayon::iter::IntoParallelIterator<Item = Self::Elem> + IntoIterator<Item = Self::Elem>
rayon::iter::IntoParallelIterator<Iter = Self::ParIter> + IntoIterator<Item = Self::Elem>
{
type Elem: Send + Sync;

type ParIter: rayon::iter::ParallelIterator<Item = Self::Elem>
+ rayon::iter::IndexedParallelIterator;

fn len(&self) -> usize;
}

Expand All @@ -49,6 +52,8 @@ where
T: Send + Sync,
{
type Elem = T;
#[cfg(feature = "concurrent")]
type ParIter = rayon::vec::IntoIter<T>;

fn len(&self) -> usize {
Vec::len(self)
Expand All @@ -60,6 +65,8 @@ where
T: Send + Sync,
{
type Elem = &'a mut T;
#[cfg(feature = "concurrent")]
type ParIter = rayon::slice::IterMut<'a, T>;

fn len(&self) -> usize {
Vec::len(self)
Expand All @@ -71,6 +78,8 @@ where
T: Send + Sync,
{
type Elem = &'a mut T;
#[cfg(feature = "concurrent")]
type ParIter = rayon::slice::IterMut<'a, T>;

fn len(&self) -> usize {
<[T]>::len(self)
Expand All @@ -82,44 +91,60 @@ where
T: Send + Sync,
{
type Elem = &'a T;
#[cfg(feature = "concurrent")]
type ParIter = rayon::slice::Iter<'a, T>;

fn len(&self) -> usize {
<[T]>::len(self)
}
}

pub trait ParallelExt: Parallel {
/// Invoke `op` in parallel, if `swc_ecma_transforms_base` is compiled with
/// Invoke `op` in parallel, if `swc_ecma_utils` is compiled with
/// concurrent feature enabled and `nodes.len()` is bigger than threshold.
///
///
/// This configures [GLOBALS], while not configuring [HANDLER] nor [HELPERS]
fn maybe_par<I, F>(&mut self, threshold: usize, nodes: I, op: F)
where
I: Items,
F: Send + Sync + Fn(&mut Self, I::Elem);
F: Send + Sync + Fn(&mut Self, I::Elem),
{
self.maybe_par_idx(threshold, nodes, |v, _, n| op(v, n))
}

/// Invoke `op` in parallel, if `swc_ecma_utils` is compiled with
/// concurrent feature enabled and `nodes.len()` is bigger than threshold.
///
///
/// This configures [GLOBALS], while not configuring [HANDLER] nor [HELPERS]
fn maybe_par_idx<I, F>(&mut self, threshold: usize, nodes: I, op: F)
where
I: Items,
F: Send + Sync + Fn(&mut Self, usize, I::Elem);
}

#[cfg(feature = "concurrent")]
impl<T> ParallelExt for T
where
T: Parallel,
{
fn maybe_par<I, F>(&mut self, threshold: usize, nodes: I, op: F)
fn maybe_par_idx<I, F>(&mut self, threshold: usize, nodes: I, op: F)
where
I: Items,
F: Send + Sync + Fn(&mut Self, I::Elem),
F: Send + Sync + Fn(&mut Self, usize, I::Elem),
{
if nodes.len() >= threshold || option_env!("SWC_FORCE_CONCURRENT") == Some("1") {
GLOBALS.with(|globals| {
use rayon::prelude::*;

let visitor = nodes
.into_par_iter()
.map(|node| {
.enumerate()
.map(|(idx, node)| {
GLOBALS.set(globals, || {
let mut visitor = Parallel::create(&*self);
op(&mut visitor, node);
op(&mut visitor, idx, node);

visitor
})
Expand All @@ -139,8 +164,8 @@ where
return;
}

for n in nodes {
op(self, n);
for (idx, n) in nodes.into_iter().enumerate() {
op(self, idx, n);
}
}
}
Expand All @@ -150,13 +175,13 @@ impl<T> ParallelExt for T
where
T: Parallel,
{
fn maybe_par<I, F>(&mut self, _threshold: usize, nodes: I, op: F)
fn maybe_par_idx<I, F>(&mut self, _threshold: usize, nodes: I, op: F)
where
I: Items,
F: Send + Sync + Fn(&mut Self, I::Elem),
F: Send + Sync + Fn(&mut Self, usize, I::Elem),
{
for n in nodes {
op(self, n);
for (idx, n) in nodes.into_iter().enumerate() {
op(self, idx, n);
}
}
}

1 comment on commit 6a42e51

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Benchmark

Benchmark suite Current: 6a42e51 Previous: f1bb365 Ratio
es/full/minify/libraries/antd 1818474063 ns/iter (± 54683097) 1987856842 ns/iter (± 368416315) 0.91
es/full/minify/libraries/d3 403154483 ns/iter (± 12195953) 409885927 ns/iter (± 21932239) 0.98
es/full/minify/libraries/echarts 1515230221 ns/iter (± 31949425) 1637754350 ns/iter (± 148982497) 0.93
es/full/minify/libraries/jquery 101581124 ns/iter (± 3790336) 113643273 ns/iter (± 14534409) 0.89
es/full/minify/libraries/lodash 112775252 ns/iter (± 6262579) 121468816 ns/iter (± 9246307) 0.93
es/full/minify/libraries/moment 61265579 ns/iter (± 3384854) 61228714 ns/iter (± 3281967) 1.00
es/full/minify/libraries/react 19755434 ns/iter (± 775000) 22635996 ns/iter (± 1208175) 0.87
es/full/minify/libraries/terser 330706170 ns/iter (± 14540902) 311686750 ns/iter (± 7552128) 1.06
es/full/minify/libraries/three 568677827 ns/iter (± 15631562) 570465801 ns/iter (± 18290456) 1.00
es/full/minify/libraries/typescript 3571262979 ns/iter (± 54199331) 3469977403 ns/iter (± 102276923) 1.03
es/full/minify/libraries/victory 848184579 ns/iter (± 7899803) 797991883 ns/iter (± 23253423) 1.06
es/full/minify/libraries/vue 161248690 ns/iter (± 9928654) 140654979 ns/iter (± 8825832) 1.15
es/full/codegen/es3 35228 ns/iter (± 1552) 32941 ns/iter (± 541) 1.07
es/full/codegen/es5 34403 ns/iter (± 901) 32603 ns/iter (± 1385) 1.06
es/full/codegen/es2015 41040 ns/iter (± 26796) 32934 ns/iter (± 1740) 1.25
es/full/codegen/es2016 34942 ns/iter (± 2809) 32818 ns/iter (± 1459) 1.06
es/full/codegen/es2017 35466 ns/iter (± 1849) 32994 ns/iter (± 517) 1.07
es/full/codegen/es2018 34561 ns/iter (± 2159) 32918 ns/iter (± 818) 1.05
es/full/codegen/es2019 34885 ns/iter (± 2613) 32892 ns/iter (± 604) 1.06
es/full/codegen/es2020 34686 ns/iter (± 1304) 32890 ns/iter (± 1347) 1.05
es/full/all/es3 214882117 ns/iter (± 21815009) 189394199 ns/iter (± 9585131) 1.13
es/full/all/es5 229608894 ns/iter (± 17621877) 178628062 ns/iter (± 6533241) 1.29
es/full/all/es2015 180936280 ns/iter (± 13191942) 147836098 ns/iter (± 7121362) 1.22
es/full/all/es2016 181773418 ns/iter (± 16581486) 151837463 ns/iter (± 9984039) 1.20
es/full/all/es2017 156415965 ns/iter (± 9641108) 156603439 ns/iter (± 11408230) 1.00
es/full/all/es2018 151956238 ns/iter (± 10149521) 148957109 ns/iter (± 10637907) 1.02
es/full/all/es2019 148134805 ns/iter (± 7973197) 142996957 ns/iter (± 3800227) 1.04
es/full/all/es2020 142802591 ns/iter (± 8309813) 135947520 ns/iter (± 7250039) 1.05
es/full/parser 734944 ns/iter (± 26318) 711168 ns/iter (± 18363) 1.03
es/full/base/fixer 26962 ns/iter (± 1754) 26395 ns/iter (± 873) 1.02
es/full/base/resolver_and_hygiene 96131 ns/iter (± 4447) 92327 ns/iter (± 2792) 1.04
serialization of ast node 214 ns/iter (± 9) 206 ns/iter (± 6) 1.04
serialization of serde 211 ns/iter (± 5) 208 ns/iter (± 4) 1.01

This comment was automatically generated by workflow using github-action-benchmark.

Please sign in to comment.