Skip to content

Commit

Permalink
feat(es/minifier): Implement trivial optimizations (#6256)
Browse files Browse the repository at this point in the history
**Description:**

1. Evaluate `Number.toString()`.
2. Mark some terser tests as passing where our output is better.
  • Loading branch information
kdy1 committed Nov 2, 2022
1 parent 108d3b8 commit 5d52ae9
Show file tree
Hide file tree
Showing 20 changed files with 117 additions and 89 deletions.
29 changes: 15 additions & 14 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/swc/tests/fixture/issues-2xxx/2728/output/input.js
@@ -1,5 +1,5 @@
function fn(bar) {
var foo = 64206..toString(16);
var foo = "face";
return eval(bar);
}
console.log(fn("foo + bar"));
@@ -1,2 +1 @@
//// [propertyAccessNumericLiterals.es6.ts]
0xffffffff.toString(), 0o01234.toString(), 0b01101101.toString(), 1234..toString(), 1e0.toString();
1 change: 1 addition & 0 deletions crates/swc_ecma_minifier/Cargo.toml
Expand Up @@ -38,6 +38,7 @@ num_cpus = "1.13.1"
once_cell = "1.10.0"
parking_lot = "0.12.0"
pretty_assertions = { version = "1.1", optional = true }
radix_fmt = "=1.0.0"
rayon = { version = "1.5.1", optional = true }
regex = "1.5.3"
retain_mut = "0.1.2"
Expand Down
54 changes: 39 additions & 15 deletions crates/swc_ecma_minifier/src/compress/pure/evaluate.rs
@@ -1,3 +1,4 @@
use radix_fmt::Radix;
use swc_atoms::js_word;
use swc_common::{util::take::Take, Spanned, SyntaxContext};
use swc_ecma_ast::*;
Expand Down Expand Up @@ -320,22 +321,45 @@ impl Pure<'_> {
// 3. Assert: If fractionDigits is undefined, then f is 0.
.map_or(Some(0f64), |arg| eval_as_number(&self.expr_ctx, &arg.expr))
{
let precision = precision.floor() as usize;
let value = num_to_fixed(num.value, precision + 1);
if precision.fract() == 0.0 {
let precision = precision.floor() as usize;
let value = num_to_fixed(num.value, precision + 1);

self.changed = true;
report_change!(
"evaluate: Evaluating `{}.toFixed({})` as `{}`",
num,
precision,
value
);

*e = Expr::Lit(Lit::Str(Str {
span: e.span(),
raw: None,
value: value.into(),
}))
self.changed = true;
report_change!(
"evaluate: Evaluating `{}.toFixed({})` as `{}`",
num,
precision,
value
);

*e = Expr::Lit(Lit::Str(Str {
span: e.span(),
raw: None,
value: value.into(),
}));
}
}

return;
}

if &*method.sym == "toString" {
if let Some(base) = args
.first()
.map_or(Some(10f64), |arg| eval_as_number(&self.expr_ctx, &arg.expr))
{
if num.value.fract() == 0.0 && (2.0..=36.0).contains(&base) && base.fract() == 0.0 {
let base = base.floor() as u8;

self.changed = true;
let value = Radix::new(num.value as usize, base).to_string().into();
*e = Expr::Lit(Lit::Str(Str {
span: e.span(),
raw: None,
value,
}))
}
}
}
}
Expand Down
10 changes: 0 additions & 10 deletions crates/swc_ecma_minifier/tests/TODO.txt
Expand Up @@ -85,9 +85,6 @@ dead_code/issue_2860_2/input.js
dead_code/return_assignment/input.js
destructuring/destructuring_dont_evaluate_with_undefined_as_default_assignment/input.js
destructuring/export_unreferenced_declarations_2/input.js
destructuring/issue_3205_2/input.js
destructuring/issue_3205_3/input.js
destructuring/issue_3205_4/input.js
destructuring/issue_3205_5/input.js
destructuring/mangle_destructuring_assign_toplevel_false/input.js
destructuring/mangle_destructuring_assign_toplevel_true/input.js
Expand Down Expand Up @@ -122,9 +119,6 @@ drop_unused/issue_2163/input.js
drop_unused/issue_2226_2/input.js
drop_unused/issue_2226_3/input.js
drop_unused/issue_2288/input.js
drop_unused/issue_2418_1/input.js
drop_unused/issue_2418_2/input.js
drop_unused/issue_2418_3/input.js
drop_unused/issue_2418_4/input.js
drop_unused/issue_2516_1/input.js
drop_unused/issue_2516_2/input.js
Expand Down Expand Up @@ -200,7 +194,6 @@ harmony/default_assign/input.js
harmony/expansion/input.js
harmony/inline_arrow_using_arguments/input.js
harmony/issue_1753_disable/input.js
harmony/issue_1898/input.js
harmony/issue_2349b/input.js
harmony/issue_2794_1/input.js
harmony/issue_2794_2/input.js
Expand Down Expand Up @@ -311,7 +304,6 @@ numbers/evaluate_1/input.js
numbers/evaluate_2/input.js
numbers/evaluate_3/input.js
numbers/evaluate_4/input.js
numbers/hex_numbers_in_parentheses_for_prototype_functions/input.js
object/concise_methods_and_mangle_props/input.js
object/dont_join_repeat_object_keys/input.js
object/prop_arrow_with_nested_this/input.js
Expand All @@ -321,7 +313,6 @@ object/prop_func_to_concise_method/input.js
object/prop_func_to_concise_method_various/input.js
parameters/destructuring_arguments_3/input.js
reduce_vars/array_forin_1/input.js
reduce_vars/chained_assignments/input.js
reduce_vars/conditional_chain_certain_part/input.js
reduce_vars/defun_catch_1/input.js
reduce_vars/defun_catch_2/input.js
Expand Down Expand Up @@ -374,7 +365,6 @@ sequences/delete_seq_4/input.js
sequences/delete_seq_5/input.js
sequences/for_init_var/input.js
sequences/for_sequences/input.js
sequences/issue_1758/input.js
sequences/issue_2062/input.js
sequences/side_effects_cascade_3/input.js
template_string/regex_2/input.js
Expand Down
Expand Up @@ -5158,7 +5158,7 @@
return buf;
}
function checked(length) {
if (length >= 0x7fffffff) throw RangeError("Attempt to allocate Buffer larger than maximum size: 0x" + 0x7fffffff.toString(16) + " bytes");
if (length >= 0x7fffffff) throw RangeError("Attempt to allocate Buffer larger than maximum size: 0x7fffffff bytes");
return 0 | length;
}
function byteLength(string, encoding) {
Expand Down
Expand Up @@ -185,7 +185,7 @@
return t;
}
function checked(e) {
if (e >= 2147483647) throw RangeError("Attempt to allocate Buffer larger than maximum size: 0x" + 2147483647..toString(16) + " bytes");
if (e >= 2147483647) throw RangeError("Attempt to allocate Buffer larger than maximum size: 0x7fffffff bytes");
return 0 | e;
}
function byteLength(e, r) {
Expand Down
Expand Up @@ -19860,7 +19860,7 @@
return r;
}
function d(e) {
if (e >= 2147483647) throw RangeError("Attempt to allocate Buffer larger than maximum size: 0x" + 2147483647..toString(16) + " bytes");
if (e >= 2147483647) throw RangeError("Attempt to allocate Buffer larger than maximum size: 0x7fffffff bytes");
return 0 | e;
}
function p(e, t) {
Expand Down
@@ -1 +1 @@
console.log(1588444911..toString(16));
console.log("5eadbeef");
10 changes: 10 additions & 0 deletions crates/swc_ecma_minifier/tests/passing.txt
Expand Up @@ -377,6 +377,9 @@ destructuring/issue_2044_ecma_6/input.js
destructuring/issue_2044_ecma_6_beautify/input.js
destructuring/issue_2140/input.js
destructuring/issue_3205_1/input.js
destructuring/issue_3205_2/input.js
destructuring/issue_3205_3/input.js
destructuring/issue_3205_4/input.js
destructuring/issue_t111_1/input.js
destructuring/issue_t111_2a/input.js
destructuring/issue_t111_2b/input.js
Expand Down Expand Up @@ -434,6 +437,9 @@ drop_unused/issue_2136_1/input.js
drop_unused/issue_2136_2/input.js
drop_unused/issue_2136_3/input.js
drop_unused/issue_2226_1/input.js
drop_unused/issue_2418_1/input.js
drop_unused/issue_2418_2/input.js
drop_unused/issue_2418_3/input.js
drop_unused/issue_2418_5/input.js
drop_unused/issue_2660_1/input.js
drop_unused/issue_2768/input.js
Expand Down Expand Up @@ -683,6 +689,7 @@ harmony/import_statement/input.js
harmony/import_statement_mangling/input.js
harmony/issue_1613/input.js
harmony/issue_1753/input.js
harmony/issue_1898/input.js
harmony/issue_2028/input.js
harmony/issue_2345/input.js
harmony/issue_2349/input.js
Expand Down Expand Up @@ -1062,6 +1069,7 @@ nullish/nullish_coalescing_parens/input.js
nullish/simplify_nullish_coalescing/input.js
numbers/comparisons/input.js
numbers/compress_numbers/input.js
numbers/hex_numbers_in_parentheses_for_prototype_functions/input.js
numbers/issue_1710/input.js
numbers/keep_numbers/input.js
numbers/keep_numbers_in_properties_as_is/input.js
Expand Down Expand Up @@ -1203,6 +1211,7 @@ reduce_vars/array_forof_2/input.js
reduce_vars/boolean_binary_assign/input.js
reduce_vars/booleans/input.js
reduce_vars/catch_var/input.js
reduce_vars/chained_assignments/input.js
reduce_vars/cond_assign/input.js
reduce_vars/conditional_chain_call/input.js
reduce_vars/conditional_chain_call_direct/input.js
Expand Down Expand Up @@ -1434,6 +1443,7 @@ sequences/func_def_5/input.js
sequences/hoist_defun/input.js
sequences/iife/input.js
sequences/issue_1685/input.js
sequences/issue_1758/input.js
sequences/issue_2313/input.js
sequences/issue_27/input.js
sequences/lift_sequences_1/input.js
Expand Down
@@ -1,8 +1,6 @@
(function () {
function f() {
var o = { a: "PASS" },
{ a: x } = o;
console.log(x);
}
f();
(function() {
var { a: x } = {
a: "PASS"
};
console.log(x);
})();
@@ -1,6 +1,5 @@
(function () {
function f(o, { a: x } = o) {
console.log(x);
}
f({ a: "PASS" });
})();
(function(o, { a: x } = o) {
console.log(x);
})({
a: "PASS"
});
@@ -1,7 +1,6 @@
(function () {
function f(o) {
var { a: x } = o;
console.log(x);
}
f({ a: "PASS" });
})();
(function(o) {
var { a: x } = o;
console.log(x);
})({
a: "PASS"
});
@@ -1,4 +1,3 @@
class C {}
class C {
}
function F() {}
(class {});
(function () {});
@@ -1,4 +1,3 @@
class C {}
class C {
}
function F() {}
(class {});
(function () {});
@@ -1,4 +1,3 @@
class C {}
class C {
}
function F() {}
(class {});
(function f() {});
@@ -1,7 +1,19 @@
class Foo {
bar() {
for (const f of [6, 5])
for (let r of [4, 3]) for (var o of [2, 1]) console.log(f, r, o);
for (const o of [
6,
5
]){
for (let f of [
4,
3
]){
for (var r of [
2,
1
])console.log(o, f, r);
}
}
}
}
new Foo().bar();

1 comment on commit 5d52ae9

@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: 5d52ae9 Previous: 655f674 Ratio
es/full/bugs-1 333499 ns/iter (± 19664) 338587 ns/iter (± 25065) 0.98
es/full/minify/libraries/antd 1821367285 ns/iter (± 21294944) 1819540785 ns/iter (± 39172952) 1.00
es/full/minify/libraries/d3 395646308 ns/iter (± 15568813) 393708825 ns/iter (± 15261028) 1.00
es/full/minify/libraries/echarts 1529611573 ns/iter (± 17266138) 1574781134 ns/iter (± 46269988) 0.97
es/full/minify/libraries/jquery 97840769 ns/iter (± 1514192) 98076612 ns/iter (± 2586366) 1.00
es/full/minify/libraries/lodash 115607946 ns/iter (± 1698643) 116716696 ns/iter (± 6988872) 0.99
es/full/minify/libraries/moment 57688801 ns/iter (± 884911) 57798336 ns/iter (± 1135112) 1.00
es/full/minify/libraries/react 20075903 ns/iter (± 419054) 19932541 ns/iter (± 309578) 1.01
es/full/minify/libraries/terser 317650668 ns/iter (± 12046523) 304546184 ns/iter (± 24425600) 1.04
es/full/minify/libraries/three 545790497 ns/iter (± 14480442) 553245544 ns/iter (± 21562229) 0.99
es/full/minify/libraries/typescript 3278454545 ns/iter (± 71952773) 3567407570 ns/iter (± 328106135) 0.92
es/full/minify/libraries/victory 829572867 ns/iter (± 12864134) 919712489 ns/iter (± 153495738) 0.90
es/full/minify/libraries/vue 150604834 ns/iter (± 6633383) 177927025 ns/iter (± 44923356) 0.85
es/full/codegen/es3 33425 ns/iter (± 622) 35298 ns/iter (± 1092) 0.95
es/full/codegen/es5 33446 ns/iter (± 431) 35433 ns/iter (± 2095) 0.94
es/full/codegen/es2015 33111 ns/iter (± 727) 35370 ns/iter (± 2469) 0.94
es/full/codegen/es2016 33354 ns/iter (± 869) 35745 ns/iter (± 3829) 0.93
es/full/codegen/es2017 33367 ns/iter (± 1849) 35002 ns/iter (± 7148) 0.95
es/full/codegen/es2018 33350 ns/iter (± 1547) 34764 ns/iter (± 24937) 0.96
es/full/codegen/es2019 33220 ns/iter (± 911) 34357 ns/iter (± 712) 0.97
es/full/codegen/es2020 33246 ns/iter (± 735) 34312 ns/iter (± 780) 0.97
es/full/all/es3 186887264 ns/iter (± 10693052) 194867417 ns/iter (± 29601477) 0.96
es/full/all/es5 176958837 ns/iter (± 6813676) 189184617 ns/iter (± 31849484) 0.94
es/full/all/es2015 142058528 ns/iter (± 5555615) 149887284 ns/iter (± 47027125) 0.95
es/full/all/es2016 142416710 ns/iter (± 6560502) 158736880 ns/iter (± 43394885) 0.90
es/full/all/es2017 140753085 ns/iter (± 6150161) 179692741 ns/iter (± 25671927) 0.78
es/full/all/es2018 140376638 ns/iter (± 8008789) 147805896 ns/iter (± 41638402) 0.95
es/full/all/es2019 145081774 ns/iter (± 5920782) 152004701 ns/iter (± 44630873) 0.95
es/full/all/es2020 139443199 ns/iter (± 7624274) 159153191 ns/iter (± 44342181) 0.88
es/full/parser 731386 ns/iter (± 27637) 759275 ns/iter (± 118680) 0.96
es/full/base/fixer 26935 ns/iter (± 1774) 27289 ns/iter (± 1882) 0.99
es/full/base/resolver_and_hygiene 91564 ns/iter (± 3220) 95250 ns/iter (± 31241) 0.96
serialization of ast node 213 ns/iter (± 2) 218 ns/iter (± 8) 0.98
serialization of serde 213 ns/iter (± 3) 216 ns/iter (± 12) 0.99

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

Please sign in to comment.