mirror of
https://github.com/swc-project/swc.git
synced 2024-12-23 13:51:19 +03:00
perf(es/minifier): Make mangler faster by merging hash sets into one (#3983)
This commit is contained in:
parent
77eb149f87
commit
107c91dd20
177
Cargo.lock
generated
177
Cargo.lock
generated
@ -225,6 +225,18 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.9.1"
|
||||
@ -264,6 +276,15 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
|
||||
|
||||
[[package]]
|
||||
name = "cast"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a"
|
||||
dependencies = [
|
||||
"rustc_version 0.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.72"
|
||||
@ -297,6 +318,17 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.34.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"textwrap 0.11.0",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "3.1.0"
|
||||
@ -312,7 +344,7 @@ dependencies = [
|
||||
"strsim",
|
||||
"termcolor",
|
||||
"terminal_size",
|
||||
"textwrap",
|
||||
"textwrap 0.14.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -497,6 +529,42 @@ dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "criterion"
|
||||
version = "0.3.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1604dafd25fba2fe2d5895a9da139f8dc9b319a5fe5354ca137cbbce4e178d10"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"cast",
|
||||
"clap 2.34.0",
|
||||
"criterion-plot",
|
||||
"csv",
|
||||
"itertools",
|
||||
"lazy_static",
|
||||
"num-traits",
|
||||
"oorandom",
|
||||
"plotters",
|
||||
"rayon",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_cbor",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"tinytemplate",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "criterion-plot"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d00996de9f2f7559f7f4dc286073197f83e92256a59ed395f9aac01fe717da57"
|
||||
dependencies = [
|
||||
"cast",
|
||||
"itertools",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.1"
|
||||
@ -557,6 +625,28 @@ dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv"
|
||||
version = "1.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1"
|
||||
dependencies = [
|
||||
"bstr",
|
||||
"csv-core",
|
||||
"itoa 0.4.8",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv-core"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctor"
|
||||
version = "0.1.21"
|
||||
@ -933,6 +1023,12 @@ dependencies = [
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "1.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.11.2"
|
||||
@ -1676,6 +1772,12 @@ version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9"
|
||||
|
||||
[[package]]
|
||||
name = "oorandom"
|
||||
version = "11.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.38"
|
||||
@ -1932,6 +2034,34 @@ version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
|
||||
|
||||
[[package]]
|
||||
name = "plotters"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a3fd9ec30b9749ce28cd91f255d569591cdf937fe280c312143e3c4bad6f2a"
|
||||
dependencies = [
|
||||
"num-traits",
|
||||
"plotters-backend",
|
||||
"plotters-svg",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "plotters-backend"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d88417318da0eaf0fdcdb51a0ee6c3bed624333bff8f946733049380be67ac1c"
|
||||
|
||||
[[package]]
|
||||
name = "plotters-svg"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "521fa9638fa597e1dc53e9412a4f9cefb01187ee1f7413076f9e6749e2885ba9"
|
||||
dependencies = [
|
||||
"plotters-backend",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pmutil"
|
||||
version = "0.5.3"
|
||||
@ -2356,6 +2486,15 @@ dependencies = [
|
||||
"semver 0.9.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
|
||||
dependencies = [
|
||||
"semver 1.0.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.6"
|
||||
@ -2482,6 +2621,16 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_cbor"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5"
|
||||
dependencies = [
|
||||
"half",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.136"
|
||||
@ -2580,7 +2729,7 @@ dependencies = [
|
||||
"if_chain",
|
||||
"lazy_static",
|
||||
"regex",
|
||||
"rustc_version",
|
||||
"rustc_version 0.2.3",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"url",
|
||||
@ -2636,7 +2785,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5"
|
||||
dependencies = [
|
||||
"discard",
|
||||
"rustc_version",
|
||||
"rustc_version 0.2.3",
|
||||
"stdweb-derive",
|
||||
"stdweb-internal-macros",
|
||||
"stdweb-internal-runtime",
|
||||
@ -2841,7 +2990,7 @@ version = "0.24.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"atty",
|
||||
"clap",
|
||||
"clap 3.1.0",
|
||||
"path-absolutize",
|
||||
"rayon",
|
||||
"relative-path",
|
||||
@ -3126,6 +3275,7 @@ dependencies = [
|
||||
"ansi_term",
|
||||
"anyhow",
|
||||
"backtrace",
|
||||
"criterion",
|
||||
"indexmap",
|
||||
"once_cell",
|
||||
"parking_lot 0.12.0",
|
||||
@ -3843,6 +3993,15 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||
dependencies = [
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.14.2"
|
||||
@ -3938,6 +4097,16 @@ dependencies = [
|
||||
"crunchy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinytemplate"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.5.1"
|
||||
|
@ -45,6 +45,11 @@ unicode-id = "0.3.0"
|
||||
[dev-dependencies]
|
||||
ansi_term = "0.12.1"
|
||||
anyhow = "1"
|
||||
criterion = "0.3.5"
|
||||
pretty_assertions = "1.1"
|
||||
swc_node_base = {version = "0.5.0", path = "../swc_node_base"}
|
||||
testing = {version = "0.18.0", path = "../testing"}
|
||||
|
||||
[[bench]]
|
||||
harness = false
|
||||
name = "full"
|
||||
|
110
crates/swc_ecma_minifier/benches/full.rs
Normal file
110
crates/swc_ecma_minifier/benches/full.rs
Normal file
@ -0,0 +1,110 @@
|
||||
//! Ported from https://github.com/privatenumber/minification-benchmarks
|
||||
|
||||
use std::fs::read_to_string;
|
||||
|
||||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||
use swc_common::{sync::Lrc, FileName, Mark, SourceMap};
|
||||
use swc_ecma_codegen::text_writer::JsWriter;
|
||||
use swc_ecma_minifier::{
|
||||
optimize,
|
||||
option::{ExtraOptions, MangleOptions, MinifyOptions},
|
||||
};
|
||||
use swc_ecma_parser::parse_file_as_module;
|
||||
use swc_ecma_transforms::{fixer, resolver_with_mark};
|
||||
use swc_ecma_visit::FoldWith;
|
||||
|
||||
pub fn bench_files(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("libs");
|
||||
group.sample_size(10);
|
||||
|
||||
let mut bench_file = |name: &str| {
|
||||
let src = read_to_string(&format!("benches/full/{}.js", name)).unwrap();
|
||||
|
||||
group.bench_function(name, |b| {
|
||||
b.iter(|| {
|
||||
// We benchmark full time, including time for creating cm, handler
|
||||
run(&src)
|
||||
})
|
||||
});
|
||||
};
|
||||
|
||||
bench_file("antd");
|
||||
bench_file("d3");
|
||||
bench_file("echarts");
|
||||
bench_file("jquery");
|
||||
bench_file("lodash");
|
||||
bench_file("moment");
|
||||
bench_file("react");
|
||||
bench_file("terser");
|
||||
bench_file("three");
|
||||
bench_file("typescript");
|
||||
bench_file("victory");
|
||||
bench_file("vue");
|
||||
}
|
||||
|
||||
criterion_group!(files, bench_files);
|
||||
criterion_main!(files);
|
||||
|
||||
fn run(src: &str) {
|
||||
testing::run_test2(false, |cm, handler| {
|
||||
let fm = cm.new_source_file(FileName::Anon, src.into());
|
||||
|
||||
let top_level_mark = Mark::fresh(Mark::root());
|
||||
|
||||
let program = parse_file_as_module(
|
||||
&fm,
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
None,
|
||||
&mut vec![],
|
||||
)
|
||||
.map_err(|err| {
|
||||
err.into_diagnostic(&handler).emit();
|
||||
})
|
||||
.map(|module| module.fold_with(&mut resolver_with_mark(top_level_mark)))
|
||||
.unwrap();
|
||||
|
||||
let output = optimize(
|
||||
program,
|
||||
cm.clone(),
|
||||
None,
|
||||
None,
|
||||
&MinifyOptions {
|
||||
compress: Some(Default::default()),
|
||||
mangle: Some(MangleOptions {
|
||||
top_level: true,
|
||||
..Default::default()
|
||||
}),
|
||||
..Default::default()
|
||||
},
|
||||
&ExtraOptions { top_level_mark },
|
||||
);
|
||||
|
||||
let output = output.fold_with(&mut fixer(None));
|
||||
|
||||
let code = print(cm, &[output], true);
|
||||
|
||||
black_box(code);
|
||||
Ok(())
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn print<N: swc_ecma_codegen::Node>(cm: Lrc<SourceMap>, nodes: &[N], minify: bool) -> String {
|
||||
let mut buf = vec![];
|
||||
|
||||
{
|
||||
let mut emitter = swc_ecma_codegen::Emitter {
|
||||
cfg: swc_ecma_codegen::Config { minify },
|
||||
cm: cm.clone(),
|
||||
comments: None,
|
||||
wr: Box::new(JsWriter::new(cm, "\n", &mut buf, None)),
|
||||
};
|
||||
|
||||
for n in nodes {
|
||||
n.emit_with(&mut emitter).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
String::from_utf8(buf).unwrap()
|
||||
}
|
129144
crates/swc_ecma_minifier/benches/full/antd.js
Normal file
129144
crates/swc_ecma_minifier/benches/full/antd.js
Normal file
File diff suppressed because one or more lines are too long
19566
crates/swc_ecma_minifier/benches/full/d3.js
vendored
Normal file
19566
crates/swc_ecma_minifier/benches/full/d3.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
91563
crates/swc_ecma_minifier/benches/full/echarts.js
Normal file
91563
crates/swc_ecma_minifier/benches/full/echarts.js
Normal file
File diff suppressed because it is too large
Load Diff
10872
crates/swc_ecma_minifier/benches/full/jquery.js
vendored
Normal file
10872
crates/swc_ecma_minifier/benches/full/jquery.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
17209
crates/swc_ecma_minifier/benches/full/lodash.js
Normal file
17209
crates/swc_ecma_minifier/benches/full/lodash.js
Normal file
File diff suppressed because it is too large
Load Diff
5670
crates/swc_ecma_minifier/benches/full/moment.js
Normal file
5670
crates/swc_ecma_minifier/benches/full/moment.js
Normal file
File diff suppressed because it is too large
Load Diff
2333
crates/swc_ecma_minifier/benches/full/react.js
vendored
Normal file
2333
crates/swc_ecma_minifier/benches/full/react.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
28309
crates/swc_ecma_minifier/benches/full/terser.js
Normal file
28309
crates/swc_ecma_minifier/benches/full/terser.js
Normal file
File diff suppressed because one or more lines are too long
38325
crates/swc_ecma_minifier/benches/full/three.js
Normal file
38325
crates/swc_ecma_minifier/benches/full/three.js
Normal file
File diff suppressed because one or more lines are too long
165906
crates/swc_ecma_minifier/benches/full/typescript.js
Normal file
165906
crates/swc_ecma_minifier/benches/full/typescript.js
Normal file
File diff suppressed because one or more lines are too long
48836
crates/swc_ecma_minifier/benches/full/victory.js
Normal file
48836
crates/swc_ecma_minifier/benches/full/victory.js
Normal file
File diff suppressed because it is too large
Load Diff
11965
crates/swc_ecma_minifier/benches/full/vue.js
Normal file
11965
crates/swc_ecma_minifier/benches/full/vue.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -13,10 +13,11 @@ pub(crate) struct Scope {
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
pub struct ScopeData {
|
||||
decls: AHashSet<Id>,
|
||||
// decls: AHashSet<Id>,
|
||||
|
||||
/// Usages in current scope.
|
||||
usages: AHashSet<Id>,
|
||||
// /// Usages in current scope.
|
||||
// usages: AHashSet<Id>,
|
||||
all: AHashSet<Id>,
|
||||
|
||||
queue: Vec<(Id, u32)>,
|
||||
}
|
||||
@ -27,7 +28,8 @@ impl Scope {
|
||||
return;
|
||||
}
|
||||
|
||||
self.data.decls.insert(id.clone());
|
||||
// self.data.decls.insert(id.clone());
|
||||
self.data.all.insert(id.clone());
|
||||
{
|
||||
if let Some((_, cnt)) = self.data.queue.iter_mut().find(|(i, _)| *i == *id) {
|
||||
*cnt += 1;
|
||||
@ -46,7 +48,8 @@ impl Scope {
|
||||
*cnt += 1;
|
||||
}
|
||||
|
||||
self.data.usages.insert(id.clone());
|
||||
// self.data.usages.insert(id.clone());
|
||||
self.data.all.insert(id.clone());
|
||||
}
|
||||
|
||||
pub(super) fn rename(
|
||||
@ -76,8 +79,10 @@ impl Scope {
|
||||
|
||||
if self.can_rename(&id, &sym, to) {
|
||||
to.insert(id.clone(), sym);
|
||||
self.data.decls.remove(&id);
|
||||
self.data.usages.remove(&id);
|
||||
// self.data.decls.remove(&id);
|
||||
// self.data.usages.remove(&id);
|
||||
self.data.all.remove(&id);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -88,6 +93,7 @@ impl Scope {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn can_rename(&self, id: &Id, symbol: &JsWord, renamed: &RenameMap) -> bool {
|
||||
if let Some(lefts) = renamed.get_by_right(symbol) {
|
||||
for left in lefts {
|
||||
@ -96,7 +102,11 @@ impl Scope {
|
||||
}
|
||||
|
||||
//
|
||||
if self.data.usages.contains(left) || self.data.decls.contains(left) {
|
||||
// if self.data.usages.contains(left) || self.data.decls.contains(left) {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
if self.data.all.contains(left) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user