ホームページ > 記事 > ウェブフロントエンド > JavaScript コードを理解して最適化する
フロントエンド エンジニアとして、誰もが JavaScript に精通していますが、この記事では、JavaScript がどのようにより深い方向、つまり JS エンジンから実行され、最適化されるかを理解します。
JS エンジン—JS エンジンの概要
1. 基本的な紹介
js エンジンは特殊な JavaScript です。通訳者。現在主流の JS エンジンとその概要を簡単に見てみましょう:
V8 - C を使用して Google によってオープンソース化されている V8 エンジンも、よく耳にするエンジンです
Rhino — Mozilla Foundation によって完全に Java で管理されているオープン ソース エンジン
SpiderMonkey — かつて Netscape で実行されていた第一世代の JS エンジンNavigator ブラウザ、現在は Firefox
NodeJS と Google Chrome の人気により、ここでは主に V8 エンジンを紹介します。動作原理は他のエンジンに興味がある方はご自身で調べていただければと思いますが、基本的には同じです。エンジンは最初に解析と変換を行います。その後、インタプリタは AST 構文ツリーを使用して、主に 2 つのことを実行します。1 つ目はマシン語バイトコードに変換し、2 つ目はエディタ (最適化コンパイラ) に渡されます。途中にはデータ分析プロセス(データのプロファイリング)もあり、主な目的はJSの動作を最適化し、最適化されたコードを機械語に変換することです。
V8 によるコア コンポーネントはそれぞれ Ignition と TurboFan です
JS コード—— 話は安いですこれを見たら、きっとこう思うでしょう、これが何のためのものかはわかった、Talk は安い、解析できるコードはあるの?それでは、次のサンプルコードを見てください。コードを分析した後、原理を詳しく紹介します。
サンプルコード 1:// first case var a = {} var b = {} console.time() for (let k = 0; k < 9999999; k++) { a[k] = 0 } for (let i = 0; i < 9999999; i++) { b[i] = 0 } console.timeEnd() // second case var a = {} var b = {} console.time() for (let k = 0; k < 9999999; k++) { a[k] = 0 } for (let i = 10000000; i < 19999999; i++) { b[i] = 0 } console.timeEnd() // third case var a = {} var b = {} console.time() for (let k = 0; k < 9999999; k++) { a[k] = 0 } for (let i = 9999999; i < 0; i--) { b[i] = 0 } console.timeEnd()上記のコードを読んでみると、その内容は非常に重要です。これは、オブジェクト a と b を定義してから属性を追加し続けるという単純な方法です。唯一の違いは、最初のケースでは a と b が同じ属性を繰り返し追加すること、2 番目のケースでは a と b が異なる属性を追加すること、そして3 番目のケースでは、a と b は同じ属性を繰り返し追加しますが、プロセス b の順序は逆です。 次に、3 つのコードの実行速度に違いはあるのか、その差は大きいのかという疑問が生じます。 (サイクル数を確認する必要はありません。すべて同じです!) 答えは、約 3 (500 ミリ秒)
V8 エンジン —— 隠しクラス
js は動的スクリプト言語であることは知っていますが、これはどういう意味ですか? オブジェクトの属性を簡単に追加/削除できます。または、その型を変更します。ほとんどの js インタープリターは、変数の属性値のアドレスをメモリに保存するために辞書構造を使用します。この方法は、Java や C# (非動的言語。もちろん、C# の動的型は別の問題です) とは異なります。 , 詳細は省きますが、js はいつでも型を変換できるため、効率が非常に低くなります。本来は、辞書構造と固定型を組み合わせて判断することにより、変数属性の場所を見つけやすくなります。値ですが、 js で達成するのは困難です。 つまり、V8 エンジンは、Hidden Class と呼ばれる非常に効率的なメソッドを使用しています。 Map、Structures、Hidden Class など、他のエンジンにも同様のメソッドがあります。ここでは、誰にとっても理解しやすいように、Shape を使用して定義します。オブジェクトを定義すると、次の内容が含まれます:
各属性の意味は次のとおりです。上の表を参照してください。Shape と組み合わせると、オブジェクトを定義するときに、JS エンジンは Shape (連続キャッシュ バッファーとして理解できます) を作成し、以下に示すように、その位置 0 と 1 に x 値と y 値が格納されます。
##両方に x と y を含む 2 つのオブジェクトを定義すると、以下に示すように、それらは形状を共有します。したがって、ここでは、同じ属性を持つオブジェクトを定義する限り、それらはすべて 1 つの形状を共有すると想像できます。任意の形状の属性値を呼び出したい場合は、同じ形状のオフセットを使用できます。そしてそれを手に入れてください。
それでは、オブジェクトに属性を追加するとどうなるでしょうか? V8 エンジンは、以下に示すように、クラス遷移の原則に基づいて位置をマークする新しい形状を作成します。
つまり、遷移チェーンを通じて 3 つの形状を作成しました。 (遷移チェーン) オブジェクトのトレーサビリティを実現します。
これを見ると、シェイプを追加するたびに必ず余分なメモリが占有されると誰もが思うはずです。そこで、最適化するために、初期化中にすべての属性を定義して最適化するようにしています。Bingo~ を参照できます。
上記の原理説明により、サンプルコードの実行速度の違いを誰もが計算して説明できるようになると思います。
最初のケース:
1. a および b の形状 (空)
2. a の形状 1....9999999
3. 形状 1 ....9999999 for b
a と b はどちらも同じ形状を共有しており、再利用できます
2 番目のケース:
1. a と b の形状 (空)
2. a
3 の形状 1....9999999. b
の形状 10000000....19999999 は、1 から 19999999 までの形状の合計を定義するため、2 番目のケースは最初のケースの 2 倍の時間がかかります。
3 番目のケース:
1. a および b の形状 (空)
2. 形状 1... .9999999 a
3 の場合。b
の場合は形状 9999999 ....1 ソース コード: https://github.com/likeconan/Alipay_Wechat_Integration
JavaScript の詳細については、以下を参照してください。 PHP 中国語 Web サイト js 特殊効果集 コラム。
以上がJavaScript コードを理解して最適化するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。