13

Object.observe () JavaScript API を使用すると、任意のコードで、任意の JavaScript オブジェクトのすべてのプロパティ変更に関する変更通知を受け取ることができます。

これは、JavaScript エンジン (つまり V8) で実行できるコード生成とパフォーマンスの最適化に深刻な影響を与えませんか? 変更通知を生成する必要がある場合、生成されたネイティブ コードはオブジェクトへのすべての書き込みをチェックする必要があるようです。特定のオブジェクトに通知が設定されているかどうかを静的に判断することはできません。したがって、チェックを最適化することはできません。

準拠している JavaScript エンジンは、この API が原因で永続的かつ重大なパフォーマンスの低下にロックインされているようです。

4

2 に答える 2

17

最新の JavaScript エンジンは、インライン キャッシングと適応再コンパイル技術を利用して、生成されたコードに対する動的ディスパッチの影響を最小限に抑えます。

V8について話している場合、オブジェクトが観察されるかどうかは、その隠しクラスにエンコードされます。インライン キャッシュ スタブと最適化されたコードの両方が、オブジェクトが期待される形状を持っているかどうかを判断するために、何らかの期待値に対して隠しクラスをすでにチェックしています。まったく同じチェックにより、オブジェクトが観測されているかどうかに関する情報が得られます。そのため、監視対象外のオブジェクトで機能するコード パスは変更されません。オブジェクトの観察を開始することは、形状を変更するのと同じように扱われます: オブジェクトの非表示クラスは、観察されたビットが設定された別のクラスに切り替えられます: これを読むことができますRuntime_SetIsObserved

同様の推論は、最適化されたコードでガードを省略し、代わりに「形状」の仮定に依存するコードを最適化解除するシステムの部分に適用されます。オブジェクトが観測されると、そのようなオブジェクトが観測されなかったという仮定に依存するすべての最適化されたコードが最適化解除されます。このように、観測されていない天体に対価は支払われません。

とはいえ、V8での現在の実装ではObject.observe、観測されたオブジェクトが正規化され (辞書表現に変換され)、観測記録のためにランタイム システムを介したラウンド トリップが必要になるため、観測されたオブジェクトに高い代償が払われます。しかし、後でこのコストを大幅に削減する上で固有の技術的な問題はありません。

于 2013-02-27T16:51:50.210 に答える
2

これは、JavaScriptエンジン(つまりV8)で実行できるコード生成とパフォーマンスの最適化に深刻な影響を与えませんか?

はい。プロキシ、ゲッター/セッター、そしておそらくプロトタイプオブジェクトとまったく同じです-それらはすべてJavaScriptで動的です。

ただし、それらの非同期性により、新しい(そしてより良い)最適化が可能になります。そして、それらは他のより非効率的なコードを時代遅れにする可能性があります。ハーモニードラフトからの目標の引用:

  • ラッパーまたはプロキシオブジェクトは不要で、メモリ効率とオブジェクトIDを提供します
  • オブジェクトのプロパティの追加/削除に関する通知を変更する
  • オブジェクトのプロパティのプロパティ記述子の変更に関する通知を変更します
  • アクセサプロパティが変更されたことをオブジェクトが手動で示す機能
  • エンジンに効率的に実装可能
  • 現在のESへのシンプルでターゲットを絞った拡張
  • 変更の非同期通知。ただし、配信待ちの変更の同期フェッチを許可します
于 2013-02-27T15:11:28.533 に答える