JavaScriptをいかに高速化するか、IE9、Firefoxの取り組み
マイクロソフトのInternet Explorerチームが運営する「IEBlog」では、先日プラットフォームプレビューが公開されたIE9の内部で、どのようにJavaScriptの実行を高速化しているのかを紹介した「The New JavaScript Engine in Internet Explorer 9」がポストされました。
一方で、FirefoxもJavaScriptの次世代エンジン「JägerMonkey」を紹介したエントリ「improving JavaScript performance with JägerMonkey」を、ブログ「Mozilla Hacks」にポストしています。
それぞれのエントリから、JavaScript高速化技術を見ていきましょう。
IE9:バックグラウンドでJavaScriptをコンパイル
3月17日にプレビュー版が公開されたマイクロソフトの次期Webブラウザ、Internet Explore 9(以下、IE9)。HTML5やCSS3、そしてSVGなど標準への準拠とともに、マルチコアCPUやGPUの能力を利用することで高速化することが特長だとされています。
IE9のJavaScript高速化技術で最大のトピックは、バックグラウンドでのコンパイルです。エントリを要約して紹介します。
JavaScript Background Compilation:
IE9ではまず素早いページ表示のために高速なインタプリタで実行をおこないつつ、バックグラウンドでスクリプトを実行していく。そして、コンパイルされたメソッドから差し替えていく。すぐにアプリケーションの実行が開始され、かつマルチコアCPUの利点を活用して高速な実行を実現できるという利点がある。
Type Optimizations:
JavaScriptの実行を高速化する重要なポイントの1つは、効果的な型システムを構築すること。IE9のスクリプトエンジンでは、動的言語実装の最新テクニックであるType Representation、Polymorphic Inline Caching (also called Type Evolution or Hidden Classes)などを採用している。
Library Optimizations:
JavaScriptアプリケーションの性能は、文字列、配列、オブジェクト、正規表現などのスクリプトライブラリに大きく依存している。IE9ではこの部分に非常に注力しており、実際のWebでの利用に合わせて慎重にチューニングしている。例えば、正規表現ライブラリは頻繁に利用されるパターンに合わせて改善しており、今後もさらに改善を続けていく。
果たしてJavaScriptはどこまで速くなるのか? 次のように書いています。
JavaScript is still limited in execution performance compared to C++ or statically typed languages. But code compilation, dynamic type inference and other innovations have enabled JavaScript to close that gap considerably.
JavaScriptは、C++などの静的型付け言語に比べるとまだ限られた実行性能しか発揮できていません。しかし、コードのコンパイル、動的型付け推論やそのほかのイノベーションにより、そのギャップをかなりの部分まで近づけられるでしょう。
Firefox:2つの方式を組み合わせ
Firefoxの次世代JavaScriptエンジン「JägerMonkey」については、エントリ「improving JavaScript performance with JägerMonkey」で説明されています。
FirefoxはこれまでSpiderMonkeyと呼ばれるJavaScriptエンジンを採用してきました。このSpiderMonkeyにFirefox 3.5から採用されたのが「Tracing」という技術。そのため、Firefox 3.5のJavaScriptエンジンは「TraceMonkey」と呼ばれています。
モジラの説明によると、SafariやChrome、OperaなどほかのWebブラウザのJavaScriptエンジンでは「method-based JIT」と呼ばれる技術を用いて、すべてのJavaScriptコードを読み込んだ上でコンパイル、実行しているのに対し、TraceMonkyでは「tracing-JIT」と呼ばれる手法を用いているのが特徴。
tracing-JITでは、JavaScriptをインタープリタで実行しながらその内容を記録し、ループなどの「hot spot」的な部分を見付け次第コンパイルして実行するという方式を採用しています。
ところが実際には想定以上にコンパイルされた部分からインタープリタ部分へ処理が戻ってしまうケースが多発し、速度の向上にそれほどつながっていないそうです。
そこで、次世代のJavaScriptエンジンではmethod-based JITとtracing-JITの良さを組み合わせるために、以下のことを行うとしています。
- WebKitのJavaScriptエンジンのコードを利用し(using some chunks of the WebKit JS engine)、method-based JITを採用する。これによりほかのJavaScriptエンジンと基本的に同程度の性能が実現する
- そこへさらにTracingを組み込むことで、ループ処理などが超高速に実行可能になる
これによって、method-based JITの全体的な高速性を得つつ、さらにtracing-JITによる高速化が実現できるだろうとのことです。
ただしこれらの作業についてはまだ初期段階に過ぎないとモジラは説明しています。
ちなみに、「Mozilla Hacks」に1月にポストされた「JavaScript speedups in Firefox 3.6」では、現在のFirefox 3.6で高速化された内容として、ガベージコレクション性能の改善、DOMプロパティなどをJIT対象に追加、文字列と正規表現処理の改善などが行われたと紹介されています。
高まるJavaScriptの重要性
JavaScriptはWebアプリケーションを構築するだけでなく、HTML5と組み合わせることによってオフライン機能やローカルのデータベース機能も利用可能になるため、本格的なアプリケーションのためのプログラミング言語となりつつあります。
しかも、PCからスマートフォン、セットトップデバイスまでクロスプラットフォームをサポートするほぼ唯一の言語です。今後その重要性はますます高まるはずで、各ブラウザによる実行性能の向上はそれを強く後押しするものとなることでしょう。