Node8.3.0でデフォルトになるTF/Iに関わるベンチマークについて
buildersconでのスライド
8.3.0 プロポーザル
大きな変更はやはりV8の6.0とWHATWG Encoding Standardが入ることです🎉
今回はV8の6.0の話をします。
これはLTS対象であるNode8へのバックポートもされNodeのバージョンを9へ上げる準備ができました。
今現在のcurrent(master branch)はv9.0.0-pre
です。
TurboFan + Ignition
V8の5.9からデフォルトになるTurboFanとIgnitionというものがあります。 今までは、Crankshaftと呼ばれるコンパイルインフラストラクチャがありましたがそれが置き換わります。
TurboFanとIgnitionを簡単に説明します。
TurboFan
JITコンパイラ。
Crankshaftから置き換わるもの。
Crankshaftではtryスコープ、ES2015の最適化(e.g. scope, class literal, for of, etc…)ができなかったですが、TurboFanではそれを可能とします。
chrome 41から段階的に使用されてました。(その頃はbaselineでTurboFanとCrankshaftでルーティングしていました)
Ignition
レジスタマシン。
モバイル端末のメモリ消費削減を目標として作られたインタプリタで、JSのコードをbytecodeにします。
V8のJITの問題点として、コードが一回実行されただけでも大量のメモリ消費をする可能性があり、メモリーオーバーヘッドを避ける必要がありました。
Flow
V8の5.9は・・・?
Nodeでは8.3.0でV8の5.9を入れる予定でしたが、6.0を待つことになりました。
6.0ではTF関連のパフォーマンスが5.9よりも改善されるからです。
どうしてもエッジケースでパフォーマンスが以前から落ちる可能性があったからです。(もちろん6.0ですべて改善されたわけではないです)
パフォーマンス
$ node benchmark/compare.js --old ./current --new ./8.3.0 arrays assert buffers child_process cluster crypto dgram dns domain es events fs http misc module net os path process querystring stream string_decoder timers tls url util v8 vm > compare-8.3.0.csv
Nodeのコアのベンチマークは上記のようにとります。(といっても普通に数日かかる量なので今回はissueのデータを使います。)
NodeのInternal ModulesのV8の5.8と5.9のパフォーマンスは以下のとおりです。
この頃は6.0がまだNodeのPRとして存在しなかったため5.9
量が多いので結論だけ言うと、劇的に改善される部分(100%以上)もあれば、劇的に遅くなる部分もあります。
例えば、buffers, events, http (!!), querystring, streams, string_decoder, url, utilは改悪になってしまってます。
今後、コアコードのパフォーマンスチューニングが必要なのではないかと思います。
webpack
8.2.1(V8 5.8)
node benchmark.js 390.80s cpu 8:16.27 total
8.3.0(V8 6.0)
node benchmark.js 385.03s cpu 7:47.66 total
結果
webpackのベンチマークはあまり詳細がでないのでこれぐらいしか言えないですが、数秒程度速くなる可能性が見込まれると思います。
ESLint
$ node Makefile.js perf
8.2.1(V8 5.8)
Loading: Load performance Run #1: 370.81079ms Load performance Run #2: 138.677693ms Load performance Run #3: 162.385871ms Load performance Run #4: 147.627503ms Load performance Run #5: 138.628092ms Load Performance median: 147.627503ms Single File: CPU Speed is 3100 with multiplier 13000000 Performance Run #1: 5423.646407ms Performance Run #2: 5004.476339ms Performance Run #3: 5003.407218ms Performance Run #4: 5906.832898ms Performance Run #5: 5831.056636ms Performance budget exceeded: 5423.646407ms (limit: 4193.548387096775ms) Multi Files (0 files): CPU Speed is 3100 with multiplier 39000000 Performance Run #1: 15058.862498ms Performance Run #2: 13073.789987ms Performance Run #3: 12624.443172ms Performance Run #4: 12712.246881ms Performance Run #5: 16854.266736ms Performance budget exceeded: 13073.789987ms (limit: 12580.645161290322ms)
8.3.0(V8 6.0)
Loading: Load performance Run #1: 353.895106ms Load performance Run #2: 146.332188ms Load performance Run #3: 137.545153ms Load performance Run #4: 137.215065ms Load performance Run #5: 141.143209ms Load Performance median: 141.143209ms Single File: CPU Speed is 3100 with multiplier 13000000 Performance Run #1: 5469.148856ms Performance Run #2: 5300.968599ms Performance Run #3: 5379.501312ms Performance Run #4: 4955.262333ms Performance Run #5: 5242.219478ms Performance budget exceeded: 5300.968599ms (limit: 4193.548387096775ms) Multi Files (0 files): CPU Speed is 3100 with multiplier 39000000 Performance Run #1: 13120.178363ms Performance Run #2: 12653.286066ms Performance Run #3: 12639.912582ms Performance Run #4: 16274.700631ms Performance Run #5: 20859.144258ms Performance budget exceeded: 13120.178363ms (limit: 12580.645161290322ms)
結果
LoadingとSingle Fileは速くなっているが、Multi Filesが遅くなっている。
また、部分部分のパフォーマンスを見ると、必ずしもNode8.3.0が速いわけではない。
しかし、基本的には改善されていると思える。