V8 JavaScriptエンジンとは(そしてその高速化について少し)
V8とは
V8はGoogleが開発しているオープンソースのJavaScript実行エンジン(JavaScriptのコードを解析し、機械語まで落とし込んで実行してくれるもの)です。
C++で書かれていて、Google Chromeで使われているほか、Node.js(サーバーサイド向けのJavaScript実行環境)などにも組み込まれています。
競合?として、MicrosoftのChakraやMozillaのSpiderMonkeyなどがありますが、全体的にパフォーマンスはV8に分があります。
公式サイトは https://v8.dev/ です。
JavaScriptエンジンのパフォーマンスについて
JavaScriptの実行エンジンで最も重要なのは「いかに高速にJavaScriptを実行できるか」です。
「どれだけ広いJavaScriptの仕様に対応できるか」や「デバッグ機能の豊富さ」も忘れてはならない点ではあるものの、やはり一番差が出るのはパフォーマンスで、そして実行エンジンのパフォーマンスの差はブラウザのパフォーマンスに大きく影響します。
そのために、ブラウザ(熾烈なシェア争いを繰り広げている)の開発元は実行エンジンのパフォーマンスの向上に努めてきました。
そのおかげか、JavaScriptは動的型付けの言語にもかかわらず、実行エンジンのおかげでかなりのハイパフォーマンスで実行することができるようになっています。(似たようなCPUインテンシブな処理をPythonとJavaSriptで書いてみて比較したらJavaScriptのほうが早いことが多い。)
V8の高速化について
そこで実際、V8がどのようにしてJavaScriptの実行を高速化をしているのか(一例だけど)を軽くまとめてみます。
- JavaScriptのコードがパースされ、抽象構文木が作られる。
- Ignitionというインタープリタが、その抽象構文木を元に、実行を始める(最適化するよりも、とにかく早く実行を開始するという雰囲気)
- Ignitionでの実行中に、ホットな関数(多く呼び出される関数)を特定し、さらにその関数がどういった種類(文字列なのか、数値なのか)の引数とともに呼び出されているのか、というデータを収集する
- そのデータをもとに、TurboFanがホットな関数をコンパイルし、最適な機械語を生成する
- その機械語を用いた実行を始める
- もしも異なったタイプの引数が来てしまった場合(最適化した機械語を用いられない場合)は最適化前の処理に戻る
こういった感じでV8はJavaScriptを実行するらしいです。
特定の関数の引数には常に同じ型のものを渡してあげると、実行エンジンに優しいコードになるということですね。