2018-12-01 16:24:26 +03:00
|
|
|
#![feature(test)]
|
2019-12-13 09:21:25 +03:00
|
|
|
extern crate test;
|
|
|
|
|
2020-07-23 20:18:22 +03:00
|
|
|
use swc_common::{FileName, DUMMY_SP};
|
2020-02-05 14:20:25 +03:00
|
|
|
use swc_ecma_ast::*;
|
2020-07-31 12:49:07 +03:00
|
|
|
use swc_ecma_parser::{lexer::Lexer, Parser, StringInput, Syntax};
|
2020-07-23 20:18:22 +03:00
|
|
|
use swc_ecma_transforms::{pass::noop, util::ExprFactory};
|
|
|
|
use swc_ecma_visit::{FoldWith, Node, Visit, VisitWith};
|
2018-12-01 16:24:26 +03:00
|
|
|
use test::Bencher;
|
|
|
|
|
2019-11-17 07:21:53 +03:00
|
|
|
static SOURCE: &str = r#"
|
2018-12-01 16:24:26 +03:00
|
|
|
'use strict';
|
|
|
|
/**
|
|
|
|
* Extract red color out of a color integer:
|
|
|
|
*
|
|
|
|
* 0x00DEAD -> 0x00
|
|
|
|
*
|
|
|
|
* @param {Number} color
|
|
|
|
* @return {Number}
|
|
|
|
*/
|
|
|
|
function red( color )
|
|
|
|
{
|
|
|
|
let foo = 3.14;
|
|
|
|
return color >> 16;
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* Extract green out of a color integer:
|
|
|
|
*
|
|
|
|
* 0x00DEAD -> 0xDE
|
|
|
|
*
|
|
|
|
* @param {Number} color
|
|
|
|
* @return {Number}
|
|
|
|
*/
|
|
|
|
function green( color )
|
|
|
|
{
|
|
|
|
return ( color >> 8 ) & 0xFF;
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* Extract blue color out of a color integer:
|
|
|
|
*
|
|
|
|
* 0x00DEAD -> 0xAD
|
|
|
|
*
|
|
|
|
* @param {Number} color
|
|
|
|
* @return {Number}
|
|
|
|
*/
|
|
|
|
function blue( color )
|
|
|
|
{
|
|
|
|
return color & 0xFF;
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* Converts an integer containing a color such as 0x00DEAD to a hex
|
|
|
|
* string, such as '#00DEAD';
|
|
|
|
*
|
|
|
|
* @param {Number} int
|
|
|
|
* @return {String}
|
|
|
|
*/
|
|
|
|
function intToHex( int )
|
|
|
|
{
|
|
|
|
const mask = '#000000';
|
|
|
|
const hex = int.toString( 16 );
|
|
|
|
return mask.substring( 0, 7 - hex.length ) + hex;
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* Converts a hex string containing a color such as '#00DEAD' to
|
|
|
|
* an integer, such as 0x00DEAD;
|
|
|
|
*
|
|
|
|
* @param {Number} num
|
|
|
|
* @return {String}
|
|
|
|
*/
|
|
|
|
function hexToInt( hex )
|
|
|
|
{
|
|
|
|
return parseInt( hex.substring( 1 ), 16 );
|
|
|
|
}
|
|
|
|
module.exports = {
|
|
|
|
red,
|
|
|
|
green,
|
|
|
|
blue,
|
|
|
|
intToHex,
|
|
|
|
hexToInt,
|
|
|
|
};"#;
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn module_clone(b: &mut Bencher) {
|
2019-12-28 05:25:54 +03:00
|
|
|
b.bytes = SOURCE.len() as _;
|
|
|
|
|
2019-01-07 13:43:47 +03:00
|
|
|
let _ = ::testing::run_test(false, |cm, handler| {
|
2019-02-10 14:49:29 +03:00
|
|
|
let fm = cm.new_source_file(FileName::Anon, SOURCE.into());
|
2019-12-14 12:51:08 +03:00
|
|
|
let lexer = Lexer::new(
|
2019-01-08 10:34:35 +03:00
|
|
|
Syntax::default(),
|
2019-12-14 12:51:08 +03:00
|
|
|
Default::default(),
|
2020-07-31 12:49:07 +03:00
|
|
|
StringInput::from(&*fm),
|
2019-02-08 07:00:58 +03:00
|
|
|
None,
|
2018-12-01 16:24:26 +03:00
|
|
|
);
|
2020-07-25 14:26:04 +03:00
|
|
|
let mut parser = Parser::new_from(lexer);
|
2019-01-07 13:43:47 +03:00
|
|
|
let module = parser
|
|
|
|
.parse_module()
|
2020-07-25 14:26:04 +03:00
|
|
|
.map_err(|e| {
|
|
|
|
e.into_diagnostic(handler).emit();
|
2019-01-07 13:43:47 +03:00
|
|
|
})
|
|
|
|
.unwrap();
|
2018-12-01 16:24:26 +03:00
|
|
|
|
2020-07-25 14:26:04 +03:00
|
|
|
for e in parser.take_errors() {
|
|
|
|
e.into_diagnostic(handler).emit();
|
|
|
|
}
|
|
|
|
|
2018-12-01 16:24:26 +03:00
|
|
|
b.iter(|| test::black_box(module.clone()));
|
|
|
|
Ok(())
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn fold_empty(b: &mut Bencher) {
|
2018-12-21 10:54:36 +03:00
|
|
|
b.bytes = SOURCE.len() as _;
|
|
|
|
|
2019-01-07 13:43:47 +03:00
|
|
|
let _ = ::testing::run_test(false, |cm, handler| {
|
2019-02-10 14:49:29 +03:00
|
|
|
let fm = cm.new_source_file(FileName::Anon, SOURCE.into());
|
2019-12-14 12:51:08 +03:00
|
|
|
let lexer = Lexer::new(
|
2019-01-08 10:34:35 +03:00
|
|
|
Syntax::default(),
|
2019-12-14 12:51:08 +03:00
|
|
|
Default::default(),
|
2020-07-31 12:49:07 +03:00
|
|
|
StringInput::from(&*fm),
|
2019-02-08 07:00:58 +03:00
|
|
|
None,
|
2018-12-01 16:24:26 +03:00
|
|
|
);
|
2020-07-25 14:26:04 +03:00
|
|
|
let mut parser = Parser::new_from(lexer);
|
2019-01-07 13:43:47 +03:00
|
|
|
let module = parser
|
|
|
|
.parse_module()
|
2020-07-25 14:26:04 +03:00
|
|
|
.map_err(|e| {
|
|
|
|
e.into_diagnostic(&handler).emit();
|
2019-01-07 13:43:47 +03:00
|
|
|
})
|
|
|
|
.unwrap();
|
2020-07-25 14:26:04 +03:00
|
|
|
|
|
|
|
for e in parser.take_errors() {
|
|
|
|
e.into_diagnostic(&handler).emit();
|
|
|
|
}
|
|
|
|
|
2020-07-23 20:18:22 +03:00
|
|
|
let mut folder = noop();
|
2018-12-01 16:24:26 +03:00
|
|
|
|
|
|
|
b.iter(|| test::black_box(module.clone().fold_with(&mut folder)));
|
|
|
|
Ok(())
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Optimized out
|
|
|
|
#[bench]
|
|
|
|
fn fold_noop_impl_all(b: &mut Bencher) {
|
2018-12-21 10:54:36 +03:00
|
|
|
b.bytes = SOURCE.len() as _;
|
|
|
|
|
2019-01-07 13:43:47 +03:00
|
|
|
let _ = ::testing::run_test(false, |cm, handler| {
|
2019-02-10 14:49:29 +03:00
|
|
|
let fm = cm.new_source_file(FileName::Anon, SOURCE.into());
|
2018-12-01 16:24:26 +03:00
|
|
|
|
2019-12-14 12:51:08 +03:00
|
|
|
let lexer = Lexer::new(
|
2019-01-08 10:34:35 +03:00
|
|
|
Syntax::default(),
|
2019-12-14 12:51:08 +03:00
|
|
|
Default::default(),
|
2020-07-31 12:49:07 +03:00
|
|
|
StringInput::from(&*fm),
|
2019-02-08 07:00:58 +03:00
|
|
|
None,
|
2018-12-01 16:24:26 +03:00
|
|
|
);
|
2020-07-25 14:26:04 +03:00
|
|
|
let mut parser = Parser::new_from(lexer);
|
2019-01-07 13:43:47 +03:00
|
|
|
let module = parser
|
|
|
|
.parse_module()
|
2020-07-25 14:26:04 +03:00
|
|
|
.map_err(|e| e.into_diagnostic(&handler).emit())
|
2019-01-07 13:43:47 +03:00
|
|
|
.unwrap();
|
2020-07-25 14:26:04 +03:00
|
|
|
|
|
|
|
for e in parser.take_errors() {
|
|
|
|
e.into_diagnostic(&handler).emit();
|
|
|
|
}
|
|
|
|
|
2020-07-23 20:18:22 +03:00
|
|
|
let mut folder = noop();
|
2018-12-01 16:24:26 +03:00
|
|
|
|
|
|
|
b.iter(|| test::black_box(module.clone().fold_with(&mut folder)));
|
|
|
|
Ok(())
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Optimized out
|
|
|
|
#[bench]
|
|
|
|
fn fold_noop_impl_vec(b: &mut Bencher) {
|
2018-12-21 10:54:36 +03:00
|
|
|
b.bytes = SOURCE.len() as _;
|
|
|
|
|
2019-01-07 13:43:47 +03:00
|
|
|
let _ = ::testing::run_test(false, |cm, handler| {
|
2019-02-10 14:49:29 +03:00
|
|
|
let fm = cm.new_source_file(FileName::Anon, SOURCE.into());
|
2019-12-14 12:51:08 +03:00
|
|
|
let lexer = Lexer::new(
|
2019-01-08 10:34:35 +03:00
|
|
|
Syntax::default(),
|
2019-12-14 12:51:08 +03:00
|
|
|
Default::default(),
|
2020-07-31 12:49:07 +03:00
|
|
|
StringInput::from(&*fm),
|
2019-02-08 07:00:58 +03:00
|
|
|
None,
|
2018-12-01 16:24:26 +03:00
|
|
|
);
|
2020-07-25 14:26:04 +03:00
|
|
|
let mut parser = Parser::new_from(lexer);
|
2019-01-07 13:43:47 +03:00
|
|
|
let module = parser
|
|
|
|
.parse_module()
|
2020-07-25 14:26:04 +03:00
|
|
|
.map_err(|e| {
|
|
|
|
e.into_diagnostic(&handler).emit();
|
2019-01-07 13:43:47 +03:00
|
|
|
})
|
|
|
|
.unwrap();
|
2020-07-25 14:26:04 +03:00
|
|
|
|
|
|
|
for e in parser.take_errors() {
|
|
|
|
e.into_diagnostic(&handler).emit();
|
|
|
|
}
|
|
|
|
|
2020-07-23 20:18:22 +03:00
|
|
|
let mut folder = noop();
|
2018-12-01 16:24:26 +03:00
|
|
|
|
|
|
|
b.iter(|| test::black_box(module.clone().fold_with(&mut folder)));
|
|
|
|
Ok(())
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
fn mk_expr() -> Expr {
|
|
|
|
Expr::Call(CallExpr {
|
|
|
|
span: DUMMY_SP,
|
|
|
|
callee: Ident::new("foo".into(), DUMMY_SP).as_callee(),
|
|
|
|
args: vec![],
|
2019-01-07 13:43:47 +03:00
|
|
|
type_args: None,
|
2018-12-01 16:24:26 +03:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn boxing_boxed_clone(b: &mut Bencher) {
|
2019-01-07 13:43:47 +03:00
|
|
|
let _ = ::testing::run_test(false, |_, _| {
|
2020-07-23 20:18:22 +03:00
|
|
|
let expr = Box::new(mk_expr());
|
2018-12-01 16:24:26 +03:00
|
|
|
|
|
|
|
b.iter(|| test::black_box(expr.clone()));
|
|
|
|
Ok(())
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn boxing_unboxed_clone(b: &mut Bencher) {
|
2019-01-07 13:43:47 +03:00
|
|
|
let _ = ::testing::run_test(false, |_, _| {
|
2018-12-01 16:24:26 +03:00
|
|
|
let expr = mk_expr();
|
|
|
|
|
|
|
|
b.iter(|| test::black_box(expr.clone()));
|
|
|
|
Ok(())
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn boxing_boxed(b: &mut Bencher) {
|
2019-01-07 13:43:47 +03:00
|
|
|
let _ = ::testing::run_test(false, |_, _| {
|
2020-07-23 20:18:22 +03:00
|
|
|
let mut folder = noop();
|
|
|
|
let expr = Box::new(mk_expr());
|
2018-12-01 16:24:26 +03:00
|
|
|
|
|
|
|
b.iter(|| test::black_box(expr.clone().fold_with(&mut folder)));
|
|
|
|
Ok(())
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn boxing_unboxed(b: &mut Bencher) {
|
2019-01-07 13:43:47 +03:00
|
|
|
let _ = ::testing::run_test(false, |_, _| {
|
2020-07-23 20:18:22 +03:00
|
|
|
let mut folder = noop();
|
2018-12-01 16:24:26 +03:00
|
|
|
let expr = mk_expr();
|
|
|
|
|
|
|
|
b.iter(|| test::black_box(expr.clone().fold_with(&mut folder)));
|
|
|
|
Ok(())
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn visit_empty(b: &mut Bencher) {
|
2018-12-21 10:54:36 +03:00
|
|
|
b.bytes = SOURCE.len() as _;
|
|
|
|
|
2020-07-25 14:26:04 +03:00
|
|
|
let _ = ::testing::run_test(false, |cm, _| {
|
2019-02-10 14:49:29 +03:00
|
|
|
let fm = cm.new_source_file(FileName::Anon, SOURCE.into());
|
2019-12-14 12:51:08 +03:00
|
|
|
let lexer = Lexer::new(
|
2019-01-08 10:34:35 +03:00
|
|
|
Syntax::default(),
|
2019-12-14 12:51:08 +03:00
|
|
|
Default::default(),
|
2020-07-31 12:49:07 +03:00
|
|
|
StringInput::from(&*fm),
|
2019-02-08 07:00:58 +03:00
|
|
|
None,
|
2018-12-01 16:24:26 +03:00
|
|
|
);
|
2020-07-25 14:26:04 +03:00
|
|
|
let mut parser = Parser::new_from(lexer);
|
|
|
|
let _module = parser.parse_module().map_err(|_| ()).unwrap();
|
2018-12-01 16:24:26 +03:00
|
|
|
|
2019-11-17 07:21:53 +03:00
|
|
|
b.iter(|| test::black_box(()));
|
2018-12-01 16:24:26 +03:00
|
|
|
Ok(())
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
#[bench]
|
|
|
|
fn visit_contains_this(b: &mut Bencher) {
|
|
|
|
fn contains_this_expr(body: &Module) -> bool {
|
|
|
|
struct Visitor {
|
|
|
|
found: bool,
|
|
|
|
}
|
|
|
|
|
2020-07-23 20:18:22 +03:00
|
|
|
impl Visit for Visitor {
|
2018-12-01 16:24:26 +03:00
|
|
|
/// Don't recurse into fn
|
2020-07-23 20:18:22 +03:00
|
|
|
fn visit_fn_expr(&mut self, _: &FnExpr, _: &dyn Node) {}
|
2018-12-01 16:24:26 +03:00
|
|
|
|
|
|
|
/// Don't recurse into fn
|
2020-07-23 20:18:22 +03:00
|
|
|
fn visit_fn_decl(&mut self, _: &FnDecl, _: &dyn Node) {}
|
|
|
|
|
|
|
|
fn visit_this_expr(&mut self, _: &ThisExpr, _: &dyn Node) {
|
|
|
|
self.found = true;
|
|
|
|
}
|
2018-12-01 16:24:26 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
let mut visitor = Visitor { found: false };
|
2020-07-23 20:18:22 +03:00
|
|
|
body.visit_with(&Invalid { span: DUMMY_SP } as _, &mut visitor);
|
2018-12-01 16:24:26 +03:00
|
|
|
visitor.found
|
|
|
|
}
|
2018-12-21 10:54:36 +03:00
|
|
|
|
|
|
|
b.bytes = SOURCE.len() as _;
|
|
|
|
|
2020-07-25 14:26:04 +03:00
|
|
|
let _ = ::testing::run_test(false, |cm, _| {
|
2019-02-10 14:49:29 +03:00
|
|
|
let fm = cm.new_source_file(FileName::Anon, SOURCE.into());
|
2019-12-14 12:51:08 +03:00
|
|
|
let lexer = Lexer::new(
|
2019-01-08 10:34:35 +03:00
|
|
|
Syntax::default(),
|
2019-12-14 12:51:08 +03:00
|
|
|
Default::default(),
|
2020-07-31 12:49:07 +03:00
|
|
|
StringInput::from(&*fm),
|
2019-02-08 07:00:58 +03:00
|
|
|
None,
|
2018-12-01 16:24:26 +03:00
|
|
|
);
|
2020-07-25 14:26:04 +03:00
|
|
|
let mut parser = Parser::new_from(lexer);
|
|
|
|
let module = parser.parse_module().map_err(|_| ()).unwrap();
|
2018-12-01 16:24:26 +03:00
|
|
|
|
|
|
|
b.iter(|| test::black_box(contains_this_expr(&module)));
|
|
|
|
Ok(())
|
|
|
|
});
|
|
|
|
}
|