swc/benches/typescript.rs
강동윤 57112fc42b
Improve transforms (#1035)
swc_ecma_transforms:
 - Fix `this` in optional chaining expression. (https://github.com/Brooooooklyn/swc-node/issues/62)
 - Optimize typescript stripper
 - Optimize fixer
2020-09-06 19:47:15 +09:00

250 lines
6.8 KiB
Rust

#![feature(test)]
extern crate test;
use std::{hint::black_box, sync::Arc};
use swc::config::{Config, JscConfig, Options, SourceMapsConfig};
use swc_common::{
errors::{ColorConfig, Handler},
FileName, FilePathMapping, SourceMap,
};
use swc_ecma_ast::Program;
use swc_ecma_parser::{JscTarget, Syntax, TsConfig};
use swc_ecma_transforms::{fixer, hygiene, resolver, typescript};
use swc_ecma_visit::FoldWith;
use test::Bencher;
static SOURCE: &str = include_str!("assets/AjaxObservable.ts");
fn mk() -> swc::Compiler {
let cm = Arc::new(SourceMap::new(FilePathMapping::empty()));
let handler = Arc::new(Handler::with_tty_emitter(
ColorConfig::Always,
true,
false,
Some(cm.clone()),
));
let c = swc::Compiler::new(cm.clone(), handler);
c
}
fn parse(c: &swc::Compiler) -> Program {
let fm = c.cm.new_source_file(
FileName::Real("rxjs/src/internal/observable/dom/AjaxObservable.ts".into()),
SOURCE.to_string(),
);
c.parse_js(
fm,
JscTarget::Es5,
Syntax::Typescript(Default::default()),
true,
true,
)
.unwrap()
}
fn as_es(c: &swc::Compiler) -> Program {
let program = parse(c);
program.fold_with(&mut typescript::strip())
}
#[bench]
fn base_tr_fixer(b: &mut Bencher) {
let c = mk();
let module = as_es(&c);
b.iter(|| {
black_box(c.run_transform(true, || {
module.clone().fold_with(&mut fixer(Some(c.comments())))
}))
});
}
#[bench]
fn base_tr_resolver_and_hygiene(b: &mut Bencher) {
let c = mk();
let module = as_es(&c);
b.iter(|| {
black_box(c.run_transform(true, || {
module
.clone()
.fold_with(&mut resolver())
.fold_with(&mut hygiene())
}))
});
}
/// This benchmark exists to know exact execution time of each pass.
#[bench]
fn config_for_file(b: &mut Bencher) {
let c = mk();
b.iter(|| {
black_box(c.config_for_file(
&Options {
config: Some(Config {
jsc: JscConfig {
target: JscTarget::Es2016,
syntax: Some(Syntax::Typescript(TsConfig {
..Default::default()
})),
..Default::default()
},
module: None,
..Default::default()
}),
swcrc: false,
is_module: true,
..Default::default()
},
&FileName::Real("rxjs/src/internal/observable/dom/AjaxObservable.ts".into()),
))
});
}
/// This benchmark exists to know exact execution time of each pass.
fn bench_codegen(b: &mut Bencher, _target: JscTarget) {
let c = mk();
let module = as_es(&c);
//TODO: Use target
b.iter(|| {
black_box(
c.print(&module, SourceMapsConfig::Bool(false), None, false)
.unwrap(),
);
})
}
macro_rules! codegen {
($name:ident, $target:expr) => {
#[bench]
fn $name(b: &mut Bencher) {
bench_codegen(b, $target);
}
};
}
codegen!(codegen_es3, JscTarget::Es3);
codegen!(codegen_es5, JscTarget::Es5);
codegen!(codegen_es2015, JscTarget::Es2015);
codegen!(codegen_es2016, JscTarget::Es2016);
codegen!(codegen_es2017, JscTarget::Es2017);
codegen!(codegen_es2018, JscTarget::Es2018);
codegen!(codegen_es2019, JscTarget::Es2019);
codegen!(codegen_es2020, JscTarget::Es2020);
fn bench_full(b: &mut Bencher, opts: &Options) {
let c = mk();
b.iter(|| {
let fm = c.cm.new_source_file(
FileName::Real("rxjs/src/internal/observable/dom/AjaxObservable.ts".into()),
SOURCE.to_string(),
);
c.process_js_file(fm, opts)
});
}
macro_rules! compat {
($name:ident, $target:expr) => {
#[bench]
fn $name(b: &mut Bencher) {
bench_full(
b,
&Options {
config: Some(Config {
jsc: JscConfig {
target: $target,
syntax: Some(Syntax::Typescript(TsConfig {
..Default::default()
})),
..Default::default()
},
module: None,
..Default::default()
}),
swcrc: false,
is_module: true,
..Default::default()
},
);
}
};
}
compat!(full_es3, JscTarget::Es3);
compat!(full_es5, JscTarget::Es5);
compat!(full_es2015, JscTarget::Es2015);
compat!(full_es2016, JscTarget::Es2016);
compat!(full_es2017, JscTarget::Es2017);
compat!(full_es2018, JscTarget::Es2018);
compat!(full_es2019, JscTarget::Es2019);
compat!(full_es2020, JscTarget::Es2020);
macro_rules! tr_only {
($name:ident, $target:expr) => {
#[bench]
fn $name(b: &mut Bencher) {
let c = mk();
let module = parse(&c);
b.iter(|| {
let program = module.clone();
let mut config = c
.config_for_file(
&Options {
config: Some(Config {
jsc: JscConfig {
target: $target,
syntax: Some(Syntax::Typescript(TsConfig {
..Default::default()
})),
..Default::default()
},
module: None,
..Default::default()
}),
swcrc: false,
is_module: true,
..Default::default()
},
&FileName::Real(
"rxjs/src/internal/observable/dom/AjaxObservable.ts".into(),
),
)
.unwrap();
let program = c.run_transform(true, || program.fold_with(&mut config.pass));
black_box(program)
});
}
};
}
tr_only!(transforms_es3, JscTarget::Es3);
tr_only!(transforms_es5, JscTarget::Es5);
tr_only!(transforms_es2015, JscTarget::Es2015);
tr_only!(transforms_es2016, JscTarget::Es2016);
tr_only!(transforms_es2017, JscTarget::Es2017);
tr_only!(transforms_es2018, JscTarget::Es2018);
tr_only!(transforms_es2019, JscTarget::Es2019);
tr_only!(transforms_es2020, JscTarget::Es2020);
#[bench]
fn parser(b: &mut Bencher) {
let c = mk();
//TODO: Use target
b.iter(|| {
black_box(parse(&c));
})
}