web-dev-qa-db-ja.com

Nodeバージョン8での非同期/待機のパフォーマンスガイドライン

async/awaitは、ノードバージョン8で使用できます。コードは、nodejsでネイティブに初めて線形になります。それはいいですね。以前の多くの記事では、v8 javascriptエンジンでは、try/catchブロックを持つ関数が最適化されていないと主張していました。現在、async/awaitはエラーを処理するためにtry/catchブロックを必要とします。では、開発者として、同じパフォーマンスを維持するために何をする必要がありますか?

10
explorer

_try/catch_はコミットでTurboFan最適化を受け取りました _9aac80f_ V8 _5.3_(ノード_v7.x_以上)。これは、_try/catch_のパフォーマンスが悪いという歴史的な記述がもはや真実ではないことを意味します。
From V8ブログ投稿

これまで、V8は、ES2015 +に見られる種類の言語機能を最適化するのに苦労していました。たとえば、V8の古典的な最適化コンパイラであるクランクシャフトに例外処理(つまり、_try/catch/finally_)サポートを追加することは実現可能になりませんでした。これは、本質的に暗黙のfinally句を持つ_for...of_のようなES6機能を最適化するV8の機能が制限されていたことを意味しました。クランクシャフトの制限と、V8のベースラインコンパイラであるfull-codegenに新しい言語機能を追加することの全体的な複雑さにより、新しいES機能が標準化されるのと同じ速さでV8に追加および最適化されることを保証することは本質的に困難でした。

幸い、IgnitionとTurboFan(V8の新しいインタープリターとコンパイラパイプライン)は、高度な制御フロー、例外処理、最近では_for...of_、ES2015からの破棄など、JavaScript言語全体を最初からサポートするように設計されました。 IgnitionとTurboFanのアーキテクチャの緊密な統合により、新しい機能をすばやく追加し、それらを迅速かつ段階的に最適化することができます。


async関数の_try/catch_は、Promise _.then_および_.catch_メソッドの単なる糖衣構文であるため、パフォーマンスは、基盤となるPromise実装によって決定されます。 Bluebird claims ネイティブのPromise実装よりもパフォーマンスが優れているため、理論的には-Bluebirdの主張が正しい場合は、ネイティブのPromise実装をBluebirdのPromise実装でオーバーライドすることで、より良い_try/catch_パフォーマンスを実現できます。
たとえば、ノードの場合:const Promise = require("bluebird")、またはglobal.Promise = require("bluebird")を使用して、グローバルにオーバーライドします。

ただし、元のPromiseの実装はJavaScriptで行われていたため、これは将来変更される可能性があることに注意してください。バグ #534 で追跡できるように、最近C++で再実装されました。

11
Sven

Node.js v8でのネイティブES2015プロミスとES2017非同期関数のパフォーマンス

Node.jsv8でのコールバックvsプロミスvs非同期関数のパフォーマンス

ネイティブChrome V8 ES2015promiseとES2017async関数の両方がBluebirdpromiseの約2倍のメモリを使用するよりも約2倍遅く実行されます

そして

結論

Node.js v8には、ネイティブのutil.promisifyの導入によってさらに強化された、ネイティブES2015promiseおよびES2017非同期関数のパフォーマンスが大幅に向上しています。

3
ponury-kostek