3

高速プロパティアクセスのv8設計要素を調べると、このトピックの最後の段落でこの点について言及しています。

非表示クラスを使用することには2つの利点があります。プロパティアクセスはディクショナリルックアップを必要とせず、V8が従来のクラスベースの最適化であるインラインキャッシングを使用できるようにします。

これは私には少し曖昧です。隠しクラスがディクショナリルックアップを必要とせず、v8が従来のクラスベースの最適化であるインラインキャッシングを使用できるようにする理由について、誰かがこれを詳しく説明できますか?

これを可能な限り詳細に行ってください。

4

1 に答える 1

4

隠しクラスの考え方は、あなたが参照した記事でよく説明されていると思います。新しいプロパティがオブジェクトに追加されるたびに、新しい隠しクラスが作成されます。オブジェクトは、この隠しクラスへの参照を保持します。さらに、hidden-classは、以前に作成されたhidden-classへの参照も保持します。例えば:

function Point(x, y) {
    this.x = x;
    this.y = y;
}

var point = new Point(10, 10);

new Point()呼び出されると、新しい隠しクラスが作成され、その隠しクラスpointへの参照が保持されます。その最初の隠しクラスは空です。つまり、プロパティが含まれていません。次に、が呼び出されると、新しい隠しクラスが作成されます。その隠しクラスは前の隠しクラスへの参照を保持し、pointはその新しい隠しクラスへの参照を更新します。が実行されると、同じことが再び起こります。this.xthis.y = y

JavaScriptの場合と同様に、プロパティをオブジェクトに動的に追加および削除することができます。プロパティアクセスを解決する方法は、マップを使用することです。一方、hidden-classesは、Cの構造体のように、プロパティを次々に線形に格納します。hidden -classesのおかげで、プロパティへのアクセスは配列の要素へのアクセスと同じくらい高速です。

次に、インラインキャッシングの意味を見てみましょう。インラインキャッシングは古い最適化手法であり、Smalltak 80やSelfなどの動的言語で使用され、JavaScriptで普及しています。実行時にプロパティにアクセスする場合、呼び出す実装コードを正確に知るために、呼び出すオブジェクトのタイプを判別する必要があります。これは、動的ディスパッチまたは遅延バインディングと呼ばれ、JavaScriptでプロパティにアクセスするとき、または2つのオペランド(整数倍精度など)を合計するときに発生します。次のコードを検討してください。

var x = 10;
var y = 10;
var total = x + y;

インラインキャッシングを使用する場合、コンパイル時var total = x + yに、汎用加算サブルーチンへのプロシージャコールでコンパイルしません。代わりに、そのコードはスタブ(インラインキャッシュ)にコンパイルされます。インラインキャッシュで生成されたコードは、受信したパラメーターのタイプを調べ、それらのタイプに特化したコードを生成します。後で別の加算が呼び出されると、タイプが以前と同じであると想定してインラインキャッシュが実行されます。ただし、タイプが異なる可能性があるため、インラインキャッシュが最初に行うことは、パラメーターのタイプをチェックすることです。タイプが異なると、キャッシュミスが発生します、およびこれらの特定のタイプに対して新しいコードが生成されます。インラインキャッシュが、ポリモーフィックインラインキャッシュ(複数のタイプのセットのエントリを持つもの)と呼ばれる多くの異なるタイプを処理できる場合。

インラインキャッシングは、関数呼び出しでパラメータータイプを推測する計算を節約し、たとえば呼び出しがループ内で発生する場合、それらの利点はより大きくなります。

インラインキャッシングは、オブジェクトのプロパティにアクセスしているときにJavaScriptで発生します。また、hidden-classesを使用すると、プロパティにすばやくアクセスできるようになります。

隠しクラスインラインキャッシュの詳細については、次の記事をお勧めします(特に、V8ハッカーのVyacheslav Egorovの最初の2つ)。

于 2014-04-09T18:27:42.687 に答える