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 *.cache
lib/6to5/templates lib/6to5/templates
test test
benchmark
Makefile Makefile
.* .*

View File

@ -99,18 +99,16 @@ for (var i of [1, 2, 3]) {
```javascript ```javascript
var obj = { var obj = {
bar: "foobar",
foo() { foo() {
return "foobar"; return "foobar";
}, },
get bar() { 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) { items.forEach(function (item) {
console.log(item); console.log(item);
}); });
}; }
``` ```
## Spread ## Spread

View File

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

View File

@ -189,25 +189,36 @@ limitations in ES5 implementations.
| | 6to5 | Traceur | esnext | es6now | es6-transpiler | | | 6to5 | Traceur | esnext | es6now | es6-transpiler |
| -------------------------- | ---- | ------- | ------ | ------ | -------------- | | -------------------------- | ---- | ------- | ------ | ------ | -------------- |
| No runtime required | ✓ | | | | ✓ | | No runtime | ✓ | | | | ✓ |
| -------------------------- | ---- | ------- | ------ | ------ | -------------- | | Source maps | ✓ | ✓ | ✓ | | ✓ |
| Array comprehension | ✓ | | ✓ | | ✓ | | **Compiler usage:** | | | | | |
| Arrow functions | ✓ | | ✓ | ✓ | ✓ | | No global pollution | ✓ | | ✓ | | ✓ |
| Block binding | ✓ | | | | ✓ | | **Syntax features:** | | | | | |
| Classes | ✓ | | ✓ | ✓ | ✓ | | Array comprehension | ✓ | ✓ | ✓ | | ✓ |
| Computed property names | ✓ | | ✓ | ✓ | ✓ | | Arrow functions | ✓ | ✓ | ✓ | ✓ | ✓ |
| Constants | ✓ | | | | ✓ | | Block binding | ✓ | ✓ | | | ✓ |
| Default parameters | ✓ | | ✓ | ✓ | ✓ | | Classes | ✓ | ✓ | ✓ | ✓ | ✓ |
| Destructuring | ✓ | | ✓ | ✓ | ✓ | | Computed property names | ✓ | ✓ | ✓ | ✓ | ✓ |
| For-of | ✓ | | ✓ | ✓ | ✓ | | Constants | ✓ | ✓ | | | ✓ |
| Generator comprehension | | | ✓ | | ✓ | | Default parameters | ✓ | ✓ | ✓ | ✓ | ✓ |
| Generators | | | ✓ | | | | Destructuring | ✓ | ✓ | ✓ | ✓ | ✓ |
| Modules | ✓ | | | ✓ | | | For-of | ✓ | ✓ | ✓ | ✓ | ✓ |
| Property method assignment | ✓ | | ✓ | ✓ | ✓ | | Generator comprehension | | ✓ | ✓ | | ✓ |
| Property name shorthand | ✓ | | ✓ | ✓ | ✓ | | Generators | | ✓ | ✓ | | |
| Rest parameters | ✓ | | ✓ | ✓ | ✓ | | Modules | ✓ | ✓ | | ✓ | |
| Spread | ✓ | | ✓ | ✓ | ✓ | | Property method assignment | ✓ | ✓ | ✓ | ✓ | ✓ |
| Template literals | ✓ | | ✓ | ✓ | ✓ | | 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) ### [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 While this can be trimmed down by selectively building the runtime, it's an
unneccesary step when a runtime can be eliminated entirely. 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](https://github.com/esnext/esnext)
esnext is **slow**, painfully so. Runtime required. 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 is the goal. This however obviously doesn't retain column mapping resulting in
the output code not being very pleasant. the output code not being very pleasant.
Runtime required.
### [es6-transpiler](https://github.com/termi/es6-transpiler) ### [es6-transpiler](https://github.com/termi/es6-transpiler)
Requires shims to compile and pollutes the global scope resulting in possible es6-transpiler requires shims to compile and pollutes the global scope resulting
collisions. 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
## Performance code output.
$ make bench

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