babel / minify

:scissors: An ES6+ aware minifier based on the Babel toolchain (beta)
https://babeljs.io/repl
MIT License
4.39k stars 225 forks source link

Sub-optimal boolean returns #29

Open vjeux opened 8 years ago

vjeux commented 8 years ago

Input:

function isTextInputElement(elem) {
  if (!elem) {
    return false;
  }

  if (elem.nodeName === 'INPUT') {
    return !!supportedInputTypes[elem.type];
  }

  if (elem.nodeName === 'TEXTAREA') {
    return true;
  }

  return false;
}

GCC Output:

function(a){return a?"INPUT"===a.nodeName?!!supportedInputTypes[a.type]:"TEXTAREA"===a.nodeName?!0:!1:!1}

Two things to be noted:

vjeux commented 8 years ago
uglify  function isTextInputElement(e){return e?"INPUT"===e.nodeName?!!supportedInputTypes[e.type]:"TEXTAREA"===e.nodeName:!1}      
babel   function isTextInputElement(a){return a?'INPUT'===a.nodeName?!!supportedInputTypes[a.type]:'TEXTAREA'===a.nodeName?!0:!1:!1}
closure function isTextInputElement(a){return a?"INPUT"===a.nodeName?!!supportedInputTypes[a.type]:"TEXTAREA"===a.nodeName?!0:!1:!1};

Only uglify solves this correctly.

fregante commented 8 years ago

(OT: is there some utility to output the above comparison at once?) Edit: found it: node scripts/benchmark.js filename.js

vjeux commented 8 years ago

I modified the benchmark script a bit

diff --git a/scripts/benchmark.js b/scripts/benchmark.js
index 3f17b38..5c9c2f9 100755
--- a/scripts/benchmark.js
+++ b/scripts/benchmark.js
@@ -17,30 +17,42 @@ if (!filename) {
   process.exit(1);
 }

+const option = process.argv[3];
+const showCode = (option === '--code');
+
+const tableChars = {
+  top: '',
+  'top-mid': '' ,
+  'top-left': '' ,
+  'top-right': '',
+  bottom: '' ,
+  'bottom-mid': '' ,
+  'bottom-left': '' ,
+  'bottom-right': '',
+  left: '',
+  'left-mid': '',
+  mid: '',
+  'mid-mid': '',
+  right: '' ,
+  'right-mid': '',
+  middle: ' ',
+};
+const tableStyle = {
+  'padding-left': 0,
+  'padding-right': 0,
+  head: ['bold'],
+};
+
 const table = new Table({
   head: ['', 'raw', 'raw win', 'gzip', 'gzip win', 'parse time', 'run'],
-  chars: {
-    top: '',
-    'top-mid': '' ,
-    'top-left': '' ,
-    'top-right': '',
-    bottom: '' ,
-    'bottom-mid': '' ,
-    'bottom-left': '' ,
-    'bottom-right': '',
-    left: '',
-    'left-mid': '',
-    mid: '',
-    'mid-mid': '',
-    right: '' ,
-    'right-mid': '',
-    middle: ' ',
-  },
-  style: {
-    'padding-left': 0,
-    'padding-right': 0,
-    head: ['bold'],
-  },
+  chars: tableChars,
+  style: tableStyle,
+});
+
+const codeTable = new Table({
+  head: ['', 'code'],
+  chars: tableChars,
+  style: tableStyle,
 });

 const results = [];
@@ -70,6 +82,7 @@ function test(name, callback) {
     gzip: gzipped.length,
     parse: parseNow,
     run: run,
+    code: result.toString(),
   });
 }

@@ -116,6 +129,11 @@ results = results.sort(function (a, b) {
 });

 results.forEach(function (result, i) {
+  codeTable.push([
+    chalk.bold(result.name),
+    result.code,
+  ]);
+
   const row = [
     chalk.bold(result.name),
     bytes(result.raw),
@@ -123,7 +141,7 @@ results.forEach(function (result, i) {
     bytes(result.gzip),
     Math.round(((gzippedCode.length / result.gzip) * 100) - 100) + '%',
     Math.round(result.parse) + 'ms',
-    Math.round(result.run) + 'ms',
+    Math.round(result.run) + 'ms'
   ];

   const style = chalk.yellow;
@@ -141,3 +159,7 @@ results.forEach(function (result, i) {
 });

 console.log(table.toString());
+if (showCode) {
+  console.log();
+  console.log(codeTable.toString());
+}
boopathi commented 8 years ago

More tests and use cases here - if_return in UglifyJS,

https://github.com/mishoo/UglifyJS2/blob/master/test/compress/if_return.js

kangax commented 8 years ago

Our output seems to be a little better now, but still not as good as closure:

function isTextInputElement(a){return!!a&&('INPUT'===a.nodeName?!!supportedInputTypes[a.type]:!('TEXTAREA'!==a.nodeName))}