Skip to content

Commit 7a85d63

Browse files
committed
Revert "Remove slow benches 1"
This reverts commit dab35a0.
1 parent bf149c4 commit 7a85d63

File tree

8 files changed

+816
-12
lines changed

8 files changed

+816
-12
lines changed

crates/swc_ecma_minifier/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,6 @@ swc_ecma_testing = { version = "15.0.0", path = "../swc_ecma_testing" }
8080
swc_malloc = { version = "1.2.3", path = "../swc_malloc" }
8181
testing = { version = "15.0.0", path = "../testing" }
8282

83-
# [[bench]]
84-
# harness = false
85-
# name = "full"
83+
[[bench]]
84+
harness = false
85+
name = "full"
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
//! Ported from https://github.com/privatenumber/minification-benchmarks
2+
3+
extern crate swc_malloc;
4+
5+
use std::{
6+
fs::read_to_string,
7+
path::{Path, PathBuf},
8+
process::Command,
9+
};
10+
11+
use codspeed_criterion_compat::{black_box, criterion_group, criterion_main, Criterion};
12+
use swc_common::{sync::Lrc, FileName, Mark, SourceMap, GLOBALS};
13+
use swc_ecma_codegen::text_writer::JsWriter;
14+
use swc_ecma_minifier::{
15+
optimize,
16+
option::{ExtraOptions, MangleOptions, MinifyOptions},
17+
};
18+
use swc_ecma_parser::parse_file_as_program;
19+
use swc_ecma_transforms_base::{fixer::fixer, resolver};
20+
use swc_ecma_utils::parallel::{Parallel, ParallelExt};
21+
use testing::CARGO_TARGET_DIR;
22+
use walkdir::WalkDir;
23+
24+
fn bench_libs(c: &mut Criterion) {
25+
let mut group = c.benchmark_group("es/minifier/libs");
26+
group.sample_size(10);
27+
28+
let mut bench_file = |name: &str| {
29+
let src = read_to_string(format!("benches/full/{name}.js")).unwrap();
30+
31+
group.bench_function(format!("es/minifier/libs/{name}"), |b| {
32+
b.iter(|| {
33+
// We benchmark full time, including time for creating cm, handler
34+
35+
run(&src)
36+
})
37+
});
38+
};
39+
40+
bench_file("antd");
41+
bench_file("d3");
42+
bench_file("echarts");
43+
bench_file("jquery");
44+
bench_file("lodash");
45+
bench_file("moment");
46+
bench_file("react");
47+
bench_file("terser");
48+
bench_file("three");
49+
bench_file("typescript");
50+
bench_file("victory");
51+
bench_file("vue");
52+
}
53+
54+
fn bench_real(c: &mut Criterion) {
55+
if std::env::var("CI").is_ok_and(|v| v == "1") {
56+
return;
57+
}
58+
59+
let input_dir = CARGO_TARGET_DIR.join("swc-minifier-inputs");
60+
61+
git_clone(
62+
"https://github.com/kdy1/swc-minifier-inputs.git",
63+
"a967ebba1668d1f78e1b5077bdbdce6ad0bfcaee",
64+
&input_dir,
65+
);
66+
67+
let mut group = c.benchmark_group("es/minifier/real");
68+
group.sample_size(10);
69+
70+
let files = expand_dirs(&input_dir);
71+
let sources = files
72+
.iter()
73+
.map(|path| read_to_string(path).unwrap())
74+
.collect::<Vec<_>>();
75+
76+
group.bench_function("es/minifier/real/sequential", |b| {
77+
b.iter(|| {
78+
// We benchmark full time, including time for creating cm, handler
79+
80+
for src in &sources {
81+
run(src);
82+
}
83+
})
84+
});
85+
86+
group.bench_function("es/minifier/real/parallel", |b| {
87+
b.iter(|| {
88+
// We benchmark full time, including time for creating cm, handler
89+
90+
GLOBALS.set(&Default::default(), || {
91+
Worker::default().maybe_par(0, &*sources, |_, src| run(src));
92+
});
93+
})
94+
});
95+
}
96+
97+
#[derive(Default, Clone, Copy)]
98+
struct Worker {}
99+
100+
impl Parallel for Worker {
101+
fn create(&self) -> Self {
102+
*self
103+
}
104+
105+
fn merge(&mut self, _other: Self) {}
106+
}
107+
108+
fn git_clone(url: &str, commit: &str, path: &Path) {
109+
if !path.join(".git").exists() {
110+
let status = Command::new("git")
111+
.arg("clone")
112+
.arg(url)
113+
.arg(path)
114+
.status()
115+
.unwrap();
116+
117+
if !status.success() {
118+
panic!("failed to clone `{}` to `{}`", url, path.display());
119+
}
120+
}
121+
122+
let status = Command::new("git")
123+
.current_dir(path)
124+
.args(["checkout", commit])
125+
.status()
126+
.unwrap();
127+
128+
if !status.success() {
129+
panic!("failed to checkout `{}` in `{}`", commit, path.display());
130+
}
131+
}
132+
133+
/// Return the whole input files as abolute path.
134+
fn expand_dirs(dir: &Path) -> Vec<PathBuf> {
135+
WalkDir::new(dir)
136+
.into_iter()
137+
.filter_map(Result::ok)
138+
.filter_map(|entry| {
139+
if entry.metadata().map(|v| v.is_file()).unwrap_or(false) {
140+
Some(entry.into_path())
141+
} else {
142+
None
143+
}
144+
})
145+
.filter(|path| path.extension().map(|ext| ext == "js").unwrap_or(false))
146+
.collect::<Vec<_>>()
147+
}
148+
149+
fn run(src: &str) {
150+
testing::run_test2(false, |cm, handler| {
151+
let fm = cm.new_source_file(FileName::Anon.into(), src.to_string());
152+
153+
let unresolved_mark = Mark::new();
154+
let top_level_mark = Mark::new();
155+
156+
let Ok(program) = parse_file_as_program(
157+
&fm,
158+
Default::default(),
159+
Default::default(),
160+
None,
161+
&mut Vec::new(),
162+
)
163+
.map_err(|err| {
164+
err.into_diagnostic(&handler).emit();
165+
})
166+
.map(|program| program.apply(resolver(unresolved_mark, top_level_mark, false))) else {
167+
return Ok(());
168+
};
169+
170+
let output = optimize(
171+
program,
172+
cm.clone(),
173+
None,
174+
None,
175+
&MinifyOptions {
176+
rename: false,
177+
compress: Some(Default::default()),
178+
mangle: Some(MangleOptions {
179+
props: None,
180+
top_level: Some(true),
181+
keep_class_names: false,
182+
keep_fn_names: false,
183+
keep_private_props: false,
184+
ie8: false,
185+
..Default::default()
186+
}),
187+
wrap: false,
188+
enclose: false,
189+
},
190+
&ExtraOptions {
191+
unresolved_mark,
192+
top_level_mark,
193+
mangle_name_cache: None,
194+
},
195+
);
196+
197+
let output = output.apply(fixer(None));
198+
199+
let code = print(cm, &[output], true);
200+
201+
black_box(code);
202+
Ok(())
203+
})
204+
.unwrap();
205+
}
206+
207+
fn print<N: swc_ecma_codegen::Node>(cm: Lrc<SourceMap>, nodes: &[N], minify: bool) -> String {
208+
let mut buf = Vec::new();
209+
210+
{
211+
let mut emitter = swc_ecma_codegen::Emitter {
212+
cfg: swc_ecma_codegen::Config::default().with_minify(minify),
213+
cm: cm.clone(),
214+
comments: None,
215+
wr: Box::new(JsWriter::new(cm, "\n", &mut buf, None)),
216+
};
217+
218+
for n in nodes {
219+
n.emit_with(&mut emitter).unwrap();
220+
}
221+
}
222+
223+
String::from_utf8(buf).unwrap()
224+
}
225+
226+
criterion_group!(bench_all, bench_libs, bench_real);
227+
criterion_main!(bench_all);

crates/swc_ecma_transforms_base/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,6 @@ testing = { version = "15.0.0", path = "../testing" }
4848
[[bench]]
4949
harness = false
5050
name = "base"
51-
# [[bench]]
52-
# harness = false
53-
# name = "parallel"
51+
[[bench]]
52+
harness = false
53+
name = "parallel"
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#![allow(clippy::redundant_closure_call)]
2+
3+
extern crate swc_malloc;
4+
5+
use codspeed_criterion_compat::{black_box, criterion_group, criterion_main, Bencher, Criterion};
6+
use par_iter::prelude::*;
7+
use swc_common::{errors::HANDLER, FileName, Mark, GLOBALS};
8+
use swc_ecma_ast::Program;
9+
use swc_ecma_parser::{Parser, StringInput, Syntax};
10+
use swc_ecma_transforms_base::helpers;
11+
12+
static SOURCE: &str = include_str!("../../swc_ecma_minifier/benches/full/typescript.js");
13+
14+
/// Benchmark a folder
15+
macro_rules! tr {
16+
($b:expr, $tr:expr) => {
17+
let _ = ::testing::run_test(false, |cm, handler| {
18+
let fm = cm.new_source_file(FileName::Anon.into(), SOURCE);
19+
20+
let mut parser = Parser::new(
21+
Syntax::Typescript(Default::default()),
22+
StringInput::from(&*fm),
23+
None,
24+
);
25+
let module = Program::Module(parser.parse_module().map_err(|_| ()).unwrap());
26+
27+
$b.iter(|| {
28+
GLOBALS.with(|globals| {
29+
(0..50).into_par_iter().for_each(|_| {
30+
GLOBALS.set(globals, || {
31+
HANDLER.set(&handler, || {
32+
helpers::HELPERS.set(&Default::default(), || {
33+
let tr = $tr();
34+
35+
let module = module.clone();
36+
black_box(module.apply(tr));
37+
})
38+
})
39+
})
40+
})
41+
})
42+
});
43+
Ok(())
44+
});
45+
};
46+
}
47+
48+
fn resolver(b: &mut Bencher) {
49+
tr!(b, || swc_ecma_transforms_base::resolver(
50+
Mark::new(),
51+
Mark::new(),
52+
false
53+
));
54+
}
55+
56+
fn hygiene(b: &mut Bencher) {
57+
tr!(b, swc_ecma_transforms_base::hygiene::hygiene);
58+
}
59+
60+
fn bench_cases(c: &mut Criterion) {
61+
let mut group = c.benchmark_group("es/base/parallel");
62+
group.sample_size(10);
63+
64+
group.bench_function("resolver/typescript", resolver);
65+
group.bench_function("hygiene/typescript", hygiene);
66+
}
67+
68+
criterion_group!(benches, bench_cases);
69+
criterion_main!(benches);

crates/swc_ecma_transforms_typescript/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,6 @@ swc_ecma_transforms_proposal = { version = "24.0.0", path = "../swc_ecma_transfo
3838
swc_ecma_transforms_testing = { version = "27.0.0", path = "../swc_ecma_transforms_testing" }
3939
testing = { version = "15.0.0", path = "../testing" }
4040

41-
# [[bench]]
42-
# harness = false
43-
# name = "compat"
41+
[[bench]]
42+
harness = false
43+
name = "compat"

0 commit comments

Comments
 (0)