作ったライブラリのベンチマークを見ている時に気がついたのだけど、ES2015 の機能を Node.js ネイティブに実行するよりも Babel で ES5 のコードに変換した方が速くなる。
検証
検証に使用したのはライブラリ
ライブラリのコードは ES2015 で書いてあるけど、Node v4 で使えない構文は使っていないので Babel を使わなくても実行できる。
.babelrc
--presets babel-preset-es2015
をつけたのと外したので確認する。
.babelrc
{
"env": {
"production": {
"only": [ "src" ],
"presets": [
"babel-preset-es2015"
]
}
}
npm run build
ビルドのタスクはこう、ベンチマークは lib に出力したものを使用する。
BABEL_ENV=production babel --out-dir=lib src
benchmark
ベンチマークは benchmark.js を使って計測している。
-
OfflineAudioContext
で 1秒分 の音をレンダリング - そのうち 0.5秒 はサイン波を出力する
- 残り 0.5秒 は「何も出力しない」をする
bench.js
const context = new wae.OfflineAudioContext(2, 44100, 44100);
const osc = context.createOscillator();
osc.start(0.25);
osc.stop(0.75);
osc.connect(context.destination);
context.startRendering().then(done);
結果
Node v6.0 で計測
"babel-preset-es2015" なし (ES2015のコードを使う)
OfflineAudioContext-sine.js
lib x 373 ops/sec ±1.46% (80 runs sampled)
"babel-preset-es2015" あり (ES5に変換したコードを使う)
OfflineAudioContext-sine.js
lib x 595 ops/sec ±1.67% (81 runs sampled)
変換した方が 1.5倍 くらい速かった。
まとめ
ES2015 のコードでパフォーマンスが必要な時は Babel で変換した方が良い。
一例での確認なので何が原因なのかがよく分からないけど、面倒なので適当に推測すると V8 の最適化が ES5 の方にかなり効くのかなと思う。(誰かもっと検証してください)