V8 JavaScriptエンジンとは(そしてその高速化について少し)

f:id:k-kty:20190111205205p:plain
V8のロゴ

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の実行を高速化をしているのか(一例だけど)を軽くまとめてみます。

  1. JavaScriptのコードがパースされ、抽象構文木が作られる。
  2. Ignitionというインタープリタが、その抽象構文木を元に、実行を始める(最適化するよりも、とにかく早く実行を開始するという雰囲気)
  3. Ignitionでの実行中に、ホットな関数(多く呼び出される関数)を特定し、さらにその関数がどういった種類(文字列なのか、数値なのか)の引数とともに呼び出されているのか、というデータを収集する
  4. そのデータをもとに、TurboFanがホットな関数をコンパイルし、最適な機械語を生成する
  5. その機械語を用いた実行を始める
  6. もしも異なったタイプの引数が来てしまった場合(最適化した機械語を用いられない場合)は最適化前の処理に戻る

こういった感じでV8はJavaScriptを実行するらしいです。

特定の関数の引数には常に同じ型のものを渡してあげると、実行エンジンに優しいコードになるということですね。