これらは私が掘り起こすことができた詳細です。JavaScript は通常、解釈されて VM 上で実行されると考えられていますが、これは、ソースを直接マシン コードにコンパイルする傾向がある最新のインタープリターには当てはまりません (IE を除く)。
クローム:V8エンジン
V8 にはコンパイル キャッシュがあります。これは、最大 5 つのガベージ コレクションのソースのハッシュを使用して、コンパイルされた JavaScript を格納します。これは、ソース コードの 2 つの同一部分が、それらがどのようにインクルードされたかに関係なく、メモリ内のキャッシュ エントリを共有することを意味します。このキャッシュは、ページがリロードされてもクリアされません。
ソース
更新 - 2015 年 3 月 19 日
Chrome チームは、JavaScript のストリーミングとキャッシングの新しい技術に関する詳細を発表しました。
- スクリプト ストリーミング
スクリプト ストリーミングは、JavaScript ファイルの解析を最適化します。[...]
バージョン 41 以降、Chrome はダウンロードが開始されるとすぐに別のスレッドで非同期スクリプトと遅延スクリプトを解析します。これは、ダウンロードが完了してからわずか数ミリ秒で解析が完了し、ページの読み込みが 10% 速くなることを意味します。
- コードキャッシング
通常、V8 エンジンは訪問のたびにページの JavaScript をコンパイルし、プロセッサが理解できる命令に変換します。コンパイルされたコードは、コンパイル時のマシンの状態とコンテキストに大きく依存するため、ユーザーがページから移動すると、このコンパイルされたコードは破棄されます。
Chrome 42 では、コンパイルされたコードのローカル コピーを保存する高度な手法が導入されているため、ユーザーがページに戻ったときにダウンロード、解析、コンパイルの手順をすべてスキップできます。これにより、すべてのページ読み込みで、Chrome はコンパイル時間を約 40% 回避し、モバイル デバイスの貴重なバッテリーを節約できます。
Opera : カラカンエンジン
実際には、これは、ソース コードが最近コンパイルされた他のプログラムのソース コードと同一であるスクリプト プログラムをコンパイルしようとするときはいつでも、コンパイラからの以前の出力を再利用し、コンパイル手順を完全にスキップすることを意味します。このキャッシュは、ニュース サービスのさまざまなニュース記事など、同じサイトからページを次々とロードする典型的なブラウジング シナリオでは非常に効果的です。これは、各ページが同じスクリプト ライブラリをロードすることが多く、場合によっては非常に大きなスクリプト ライブラリをロードするためです。
したがって、JavaScript はページのリロード後にキャッシュされるため、同じスクリプトに対する 2 つのリクエストが再コンパイルされることはありません。
ソース
Firefox : SpiderMonkey エンジン
SpiderMonkey はNanojit
、JIT コンパイラをネイティブ バックエンドとして使用します。マシンコードをコンパイルするプロセスは、ここで見ることができます。つまり、スクリプトがロードされると再コンパイルされるように見えます。ただし、の内部を詳しく見てみるNanojit
と、コンパイルを追跡するために使用される上位レベルの monitorjstracer
が、コンパイル中に 3 つの段階を経て遷移し、次のようなメリットがあることがわかりNanojit
ます。
トレース モニタの初期状態は監視です。これは、spidermonkey がバイトコードを解釈していることを意味します。Spidermonkey が逆方向ジャンプ バイトコードを解釈するたびに、モニターは、ジャンプ先のプログラム カウンター (PC) 値がジャンプされた回数を記録します。この数は、PC のヒット数と呼ばれます。特定の PC のヒット カウントがしきい値に達すると、ターゲットはホットと見なされます。
モニターは、ターゲット PC がホットであると判断すると、フラグメントのハッシュテーブルを調べて、そのターゲット PC のネイティブ コードを保持するフラグメントがあるかどうかを確認します。そのようなフラグメントが見つかった場合、実行モードに移行します。それ以外の場合は、記録モードに移行します。
これはhot
、コードのフラグメントの場合、ネイティブ コードがキャッシュされることを意味します。つまり、再コンパイルする必要はありません。これらのハッシュ化されたネイティブ セクションがページの更新間で保持されるかどうかは明らかではありません。しかし、私は彼らがそうだと思います。誰かがこれを裏付ける証拠を見つけることができれば、素晴らしい.
編集: Mozilla 開発者の Boris Zbarsky が、Gecko はコンパイル済みスクリプトをまだキャッシュしていないと述べていることが指摘されています。この SO answerから取得。
Safari : JavaScriptCore/SquirelFish エンジン
この実装に対する最良の答えは、すでに他の誰かによって与えられていると思います。
現在、バイトコード (またはネイティブ コード) をキャッシュしていません。これは
私たちが検討したオプションですが、現在、コード生成は
JS 実行時間のわずかな部分 (< 2%) であるため
、現時点では追求していません。
これは、Safari の主任開発者であるMaciej Stachowiakによって書かれました。ですから、それが真実であると考えることができると思います。
他の情報は見つかりませんでしたが、最新のSquirrelFish Extreme
エンジンの速度向上について詳しくはこちらをご覧ください。冒険したい場合は、こちらでソース コードを参照してください。
IE : チャクラエンジン
このフィールドには、IE9 の JavaScript エンジン (チャクラ) に関する現在の情報はありません。何か知ってる人いたらコメントください。
これはまったく非公式ですが、IE の古いエンジンの実装について、Eric Lippert ( JScript の MS 開発者) はブログの返信で次のように述べています。
JScript Classic は、JScript Classic プログラムを実行する前に、コードを完全に構文チェックし、完全な解析ツリーを生成し、バイトコードを生成するという意味で、コンパイルされた言語のように機能します。次に、バイトコード インタープリターを介してバイトコードを実行します。その意味で、JScript は Java と同じように「コンパイル」されています。違いは、JScript では独自のバイトコードを保持したり調べたりすることができないことです。また、バイトコードは JVM バイトコードよりもはるかに高レベルです。JScript クラシック バイトコード言語は解析ツリーの線形化にすぎませんが、JVM バイトコードは明らかに低レベルのスタック マシンで動作するように意図されています。
これは、バイトコードがまったく保持されないことを示しているため、バイトコードはキャッシュされません。