JavaScriptエンジンの基本:一般的なフォームとインラインキャッシュ。 パート2

みなさんこんにちは! 「情報システムのセキュリティ」コースは2週間で始まるため、本日は記事の第2部を公開したいと思います。 ここで最初の部分を読むことができます 。 それでは始めましょう。

インラインキャッシュ(IC)

フォームの背後にある主なアイデアは、インラインキャッシュまたはICの概念です。 これらは高速JavaScriptの重要なコンポーネントです! JavaScriptエンジンはICを使用して、コストのかかる検索の回数を減らすために、オブジェクトのプロパティの場所に関する情報を記憶します。



入力としてオブジェクトを受け取り、そこからxプロパティをロードするgetX関数があります。

 function getX(o) { return ox; } 

この関数をJSCで実行すると、次のバイトコードが取得されます。



最初のget_by_idは、最初の引数(arg1)から'x'プロパティをロードし、結果をloc0ます。 次の文は、 loc0に保存したものを返します。
JSCは、2つの初期化されていないスロットで構成されるget_by_idインラインキャッシュも埋め込みます。



ここで、 { x: 'a' }オブジェクトとともにgetXを呼び出すと仮定します。 このオブジェクトには'x'プロパティがあり、その形状にはプロパティのオフセットと属性が格納されていることが既にわかっています。 関数を初めて実行すると、 get_by_idステートメントは'x'プロパティを検索し、その値がオフセット0に格納されていることを検出します。



命令に組み込まれたget_by_id ICは、プロパティが見つかった形状とオフセットを保存します。



その後のICの起動では、フォームを比較するだけで済み、以前と同じ場合は、保存されたオフセットから値をロードするだけです。 特に、JavaScriptエンジンが以前に書き留めたフォームのオブジェクトを見ると、これらのプロパティに関する一般的な情報を要求する必要がなくなります。代わりに、プロパティに関する情報の高価な検索を完全にスキップできます。 これは、毎回プロパティを探す時間を費やすよりも大幅に高速です。

アレイの効率的なストレージ

配列の場合、配列インデックスを保存するのが一般的です。 このようなプロパティの値は、配列要素と呼ばれます。 配列の各要素のプロパティ属性を個別の配列に保存するのは無駄です。 代わりに、JavaScriptエンジンは、配列でインデックス付けされたプロパティがデフォルトで書き込み、列挙、および構成可能であるという事実に依存しており、他の名前付きプロパティとは別に配列要素も保存します。

次の配列を検討してください。

 const array = [ '#jsconfeu', ]; 

エンジンは、単位の長さの配列を格納し、 'length'プロパティのオフセットと属性を含むシェイプをポイントします。



これは、すでに見たものに似ています...しかし、配列の要素の値はどこにありますか?



各配列には、配列によってインデックス付けされたすべてのプロパティ値を含む個別の要素バッキングストアがあります。 JavaScriptエンジンは、通常は書き込み可能、​​列挙可能、および構成可能なため、配列の要素のプロパティ属性を保存する必要はありません。

しかし、構成が突然利用できなくなったらどうなりますか? 配列要素のプロパティの属性を変更するとどうなりますか?

 // Please don't ever do this! const array = Object.defineProperty( [], '0', { value: 'Oh noes!!1', writable: false, enumerable: false, configurable: false, } ); 

上記のコードスニペットは、 '0'というプロパティを定義し(この場合、配列のインデックスであることがわかります)、属性値をデフォルト以外の値に変更します。

このような極端な場合、JavaScriptエンジンは、アイテムのバックアップストレージ全体を、配列インデックスをプロパティ属性にマップするディクショナリとして提示します。



配列の1つの要素のみにデフォルト以外の属性がある場合でも、要素のバックアップコピーのストレージ全体が低速で非効率的な動作モードになります。 配列インデックスでObject.definePropertyしないでください! (原理的にそれを使うべき理由さえ知りません。それは奇妙で不合理に思えます。)

結論

JavaScriptエンジンがオブジェクトと配列を保存する方法、フォームとインラインキャッシュがさまざまな操作を最適化する方法を学びました。 また、この記事では、コードのパフォーマンスを向上させるためのJavaScriptの実用的なヒントをいくつか示します。


これで、記事は完成したと見なすことができます。 確立された伝統によると、私たちはあなたのコメントを待っており、有名なウイルスアナリストとパートタイムの先生であるAlexander Kolesnikovが本日開催するコース「情報システムのセキュリティ」に関する公開ウェビナーにサインアップすることを勧めます。

最初の部分を読んでください。

Source: https://habr.com/ru/post/J447220/


All Articles