add benchmark

This commit is contained in:
Sebastian McKenzie 2014-10-08 15:37:02 +11:00
parent 577877b813
commit 9f08c39c75
7 changed files with 253 additions and 40 deletions

View File

@ -3,5 +3,6 @@ node_modules
*.cache
lib/6to5/templates
test
benchmark
Makefile
.*

View File

@ -99,18 +99,16 @@ for (var i of [1, 2, 3]) {
```javascript
var obj = {
bar: "foobar",
foo() {
return "foobar";
},
get bar() {
return this._bar;
},
set bar() {
set bar(val) {
this._bar = val;
}
};
```
@ -131,7 +129,7 @@ function printList(name, ...items) {
items.forEach(function (item) {
console.log(item);
});
};
}
```
## Spread

View File

@ -3,7 +3,7 @@ MOCHA_CMD = node_modules/mocha/bin/_mocha
export NODE_ENV = test
.PHONY: clean test test-cov test-travis publish
.PHONY: clean test test-cov test-travis publish bench
clean:
rm -rf coverage templates.json
@ -11,6 +11,9 @@ clean:
test:
$(MOCHA_CMD)
bench:
node node_modules/matcha/bin/_matcha
test-cov:
make clean
node $(ISTANBUL_CMD) $(MOCHA_CMD) --

View File

@ -189,25 +189,36 @@ limitations in ES5 implementations.
| | 6to5 | Traceur | esnext | es6now | es6-transpiler |
| -------------------------- | ---- | ------- | ------ | ------ | -------------- |
| No runtime required | ✓ | | | | ✓ |
| -------------------------- | ---- | ------- | ------ | ------ | -------------- |
| Array comprehension | ✓ | | ✓ | | ✓ |
| Arrow functions | ✓ | | ✓ | ✓ | ✓ |
| Block binding | ✓ | | | | ✓ |
| Classes | ✓ | | ✓ | ✓ | ✓ |
| Computed property names | ✓ | | ✓ | ✓ | ✓ |
| Constants | ✓ | | | | ✓ |
| Default parameters | ✓ | | ✓ | ✓ | ✓ |
| Destructuring | ✓ | | ✓ | ✓ | ✓ |
| For-of | ✓ | | ✓ | ✓ | ✓ |
| Generator comprehension | | | ✓ | | ✓ |
| Generators | | | ✓ | | |
| Modules | ✓ | | | ✓ | |
| Property method assignment | ✓ | | ✓ | ✓ | ✓ |
| Property name shorthand | ✓ | | ✓ | ✓ | ✓ |
| Rest parameters | ✓ | | ✓ | ✓ | ✓ |
| Spread | ✓ | | ✓ | ✓ | ✓ |
| Template literals | ✓ | | ✓ | ✓ | ✓ |
| No runtime | ✓ | | | | ✓ |
| Source maps | ✓ | ✓ | ✓ | | ✓ |
| **Compiler usage:** | | | | | |
| No global pollution | ✓ | | ✓ | | ✓ |
| **Syntax features:** | | | | | |
| Array comprehension | ✓ | ✓ | ✓ | | ✓ |
| Arrow functions | ✓ | ✓ | ✓ | ✓ | ✓ |
| Block binding | ✓ | ✓ | | | ✓ |
| Classes | ✓ | ✓ | ✓ | ✓ | ✓ |
| Computed property names | ✓ | ✓ | ✓ | ✓ | ✓ |
| Constants | ✓ | ✓ | | | ✓ |
| Default parameters | ✓ | ✓ | ✓ | ✓ | ✓ |
| Destructuring | ✓ | ✓ | ✓ | ✓ | ✓ |
| For-of | ✓ | ✓ | ✓ | ✓ | ✓ |
| Generator comprehension | | ✓ | ✓ | | ✓ |
| Generators | | ✓ | ✓ | | |
| Modules | ✓ | ✓ | | ✓ | |
| Property method assignment | ✓ | ✓ | ✓ | ✓ | ✓ |
| Property name shorthand | ✓ | ✓ | ✓ | ✓ | ✓ |
| Rest parameters | ✓ | ✓ | ✓ | ✓ | ✓ |
| Spread | ✓ | ✓ | ✓ | ✓ | ✓ |
| Template literals | ✓ | ✓ | ✓ | ✓ | ✓ |
#### Performance
$ make bench
![Output size (including runtime) (lower is better)](http://i.imgur.com/hAybrA2.png)
![Compile speed (higher is better)](http://i.imgur.com/yMwMvhg.png)
### [Traceur](https://github.com/google/traceur-compiler)
@ -215,10 +226,6 @@ Traceur requires quite a bulky runtime (~75KB) and produces quite verbose code.
While this can be trimmed down by selectively building the runtime, it's an
unneccesary step when a runtime can be eliminated entirely.
Instead of mapping to a runtime, 6to5 maps directly to the equivalent ES5. This
means that your transpiled code will be as simple as possible and is
**exactly** the equivalent ES5.
### [esnext](https://github.com/esnext/esnext)
esnext is **slow**, painfully so. Runtime required.
@ -229,13 +236,9 @@ Doesn't output sourcemaps. This is cited as a positive as line-to-line mapping
is the goal. This however obviously doesn't retain column mapping resulting in
the output code not being very pleasant.
Runtime required.
### [es6-transpiler](https://github.com/termi/es6-transpiler)
Requires shims to compile and pollutes the global scope resulting in possible
collisions.
## Performance
$ make bench
es6-transpiler requires shims to compile and pollutes the global scope resulting
in possible collisions. es6-transpiler maps line-by-line, just like es6now, this
results in the same issues such as lack of column information and unpleasant
code output.

99
benchmark/fixtures/all.js Normal file
View File

@ -0,0 +1,99 @@
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var obj = {};
var foo = "foo";
var bar = "bar";
// constants
const MULTIPLIER = 5;
// classes
class Foo {
constructor() {
this.foo = "bar";
}
}
class Bar extends Foo {
constructor() {
super();
}
// default parameters
go(foo = "bar", bar = "foo") {
}
get foo() {
return this._foo;
}
set foo(val) {
this._foo = val + " foo!";
}
}
// arrow functions
arr.map(x => x * x);
// block binding
for (let key in arr) {
let val = arr[key];
console.log(key, val);
}
// computed property names
obj = {
["foo" + bar]: "foobar"
};
// destructuring
var [a, [b], c, d] = ["hello", [", ", "junk"], ["world"]];
console.log(a + b + c);
// array comprehension
// [for (i of [1, 2, 3]) i * i]; // not supported by es6now
// for-of
for (var i of [1, 2, 3]) {
console.log(i * i);
}
// property method assignment
obj = {
foo() {
return "foobar";
},
get bar() {
return this._bar;
},
set bar(val) {
this._bar = val;
}
};
// property name shorthand
function f(x, y) {
return { x, y };
}
// rest parameters
function printList(name, ...items) {
console.log("list %s has the following items", name);
items.forEach(function (item) {
console.log(item);
});
}
// spread
function add(x, y) {
return x + y;
}
var numbers = [5, 10];
add(...numbers);
// template literals
var x = 5;
var y = 10;
console.log(`${x} + ${y} = ${x + y}`);

88
benchmark/index.js Normal file
View File

@ -0,0 +1,88 @@
Error.stackTraceLimit = Infinity;
var traceur = require("traceur");
var es6tr = require("es6-transpiler");
var es6now = require("es6now");
var esnext = require("esnext");
var to5 = require("../lib/6to5/node");
var matcha = require("matcha");
var stream = require("stream");
var path = require("path");
var fs = require("fs");
var vm = require("vm");
var _ = require("lodash");
var readResolve = function (filename) {
return fs.readFileSync(require.resolve(filename), "utf8");
};
var compilers = {
"6to5": {
compile: function (code, filename) {
return to5.transform(code, { filename: filename });
}
},
traceur: {
runtime: readResolve("traceur/bin/traceur-runtime.js"),
compile: function (code, filename) {
return traceur.compile(code, {
modules: "commonjs",
experimental: true
});
}
},
esnext: {
runtime: readResolve("esnext/node_modules/regenerator/runtime.js"),
compile: function (code, filename) {
return esnext.compile(code).code;
}
},
es6now: {
runtime: readResolve("es6now/runtime/ES6.js"),
compile: function (code, filename) {
return es6now.translate(code);
}
},
"es6-transpiler": {
compile: function (code, filename) {
var result = es6tr.run({ src: code });
if (result.errors.length) throw new Error(result.join("; "));
return result.src;
}
}
};
_.each(fs.readdirSync(__dirname + "/fixtures"), function (name) {
var alias = path.basename(name, path.extname(name));
suite(alias, function () {
set("delay", 0);
var loc = __dirname + "/fixtures/" + name;
var code = fs.readFileSync(loc, "utf8");
before(function () {
_.each(compilers, function (compiler, name) {
var output = compiler.compile(code, loc);
if (compiler.runtime) output = compiler.runtime + "\n" + output;
var kilo = (output.length / 1024).toFixed(2);
console.log(
matcha.utils.color(matcha.utils.padBefore(kilo + "KB", 22), "cyan"),
matcha.utils.color("» " + name, "gray")
);
});
});
_.each(compilers, function (compiler, name) {
bench(name, function () {
compiler.compile(code, loc);
});
});
});
});

View File

@ -17,8 +17,24 @@
"6to5": "./bin/6to5",
"6to5-node": "./bin/6to5-node"
},
"keywords": [
"es6-transpiler",
"scope",
"harmony",
"blockscope",
"block-scope",
"let",
"const",
"var",
"es6",
"transpile",
"transpiler",
"traceur",
"6to5"
],
"scripts": {
"test": "mocha"
"bench": "make bench",
"test": "make test"
},
"dependencies": {
"ast-types": "0.5.0",
@ -32,7 +48,12 @@
"es6-shim": "^0.18.0"
},
"devDependencies": {
"es6-transpiler": "0.7.17",
"istanbul": "0.3.2",
"matcha": "0.5.0",
"mocha": "1.21.4",
"istanbul": "0.3.2"
"traceur": "0.0.66",
"esnext": "0.11.1",
"es6now": "0.8.11"
}
}