JavaScriptの実行速度を劇的に改善するasm.jsの特徴は、CやC++のような言語をJavaScriptのサブセットで記述すること
6月のリリース予定で現在開発が進んでいるFirefox 22では、JavaScriptのサブセット言語仕様であるasm.jsと、asm.jsに最適化したJavaScriptエンジンのOdionMonkeyが搭載予定とのことです。この両者の組み合わせは、JavaScriptを型つき言語として事前コンパイルすることで、いま以上に高速に実行できると期待されています。
asm.jsとは、jQueryのようなJavaScriptライブラリのようなものでも、Node.jsのようなフレームワーク実装のことでもなく、JavaScriptを基にしたサブセットの言語仕様です。
新しい言語を作るのではなく、既存のJavaScript文法をそのまま利用しつつ高速化を実現するasm.jsとは、どのようなものなのでしょうか? 調べてみました。
メモリアンセーフな言語を、セーフな仮想マシン上で効果的に記述する
asm.js仕様によると、最大の特徴は「CやC++のようなメモリアンセーフな言語を、セーフな仮想マシン上で効果的に記述する」ことにあります。つまり、JavaScriptのままでC/C++言語のように静的型つきで事前コンパイル可能なコードを記述しようというわけです。
asm.js仕様から、概要の部分を引用しましょう。
This specification defines asm.js, a strict subset of JavaScript that can be used as a low-level, efficient target language for compilers. This sublanguage effectively describes a safe virtual machine for memory-unsafe languages like C or C++. A combination of static and dynamic validation allows JavaScript engines to employ an ahead-of-time (AOT) optimizing compilation strategy for valid asm.js code.
この仕様はasm.jsを定義している。これはJavaScriptの絞り込まれたサブセットであり、コンパイラ用の低レベルで効果的なターゲット言語として利用可能だ。このサブ言語は、CやC++のようなメモリアンセーフな言語のために、セーフな仮想マシンを効果的に記述する。静的バリデーションと動的バリデーションの組み合わせは、有効なasm.jsコードに対してJavaScriptエンジンが、事前最適化コンパイラを用いる戦略を実現する。(追記:誤訳がいくつかありましたので修正しました)
JavaScriptは動的型付け言語であり、変数の型が事前に決まっていないために、演算や代入など、何をするにも型チェックや型変換が発生します。これがJavaScriptの実行速度の遅さの要因の1つになっていました。また、インタプリタ型の実行形式をとることも遅さの要因です。asm.jsと、それに最適化したJavaScriptエンジンであるOdionMonkeyは、こうした遅さの要因をJavaScriptのままで解決する技術の組み合わせといえます。さらに、遅さのもう1つの要因であるガベージコレクションも止めてしまうと説明されています。
従来より劇的に高速で、ネイティブコードの2倍程度の実行時間
asm.jsの最大のポイントは、こうした言語仕様上の課題の解決を、TypeScriptやCoffeeScriptのような新しい言語や構文を作るのではなく、JavaScriptのまま、そのサブセットを定義することで実現したことです。これによってasm.js対応のコードは、従来のブラウザでは通常のJavaScriptプログラムとして実行され、asm.jsに最適化されたブラウザでは事前コンパイルが走って高速に実行されることになります。
MozillaのAlon Zakai氏が公開しているプレゼンテーションでは、asm.jsとOdionMonkeyの組み合わせによるベンチマーク結果が公開されています。それによると、従来のFirefoxやChromeでのJavaScriptの実行速度より圧倒的に高速で、ネイティブコードの2倍程度の時間でベンチマークを走らせていることが分かります。
Luke Wagner氏のブログによると、Mozillaはすでにデスクトップ向けブラウザではx86/x64のWindows、MacOS、Linux対応をしており、ARM対応もほとんど終わっているとのことです。
At the moment, we have x86/x64 support on desktop Windows/Mac/Linux and support for mobile Firefox on ARM is almost done.
特にプロセッサが非力なモバイルデバイスでは、実行速度の遅さからWebアプリケーションよりもネイティブアプリケーションを選択するケースがあります。JavaScriptのコードがより高速に実行できるようになることのメリットは非常に大きいはずです。
次の記事では、asm.jsの概要を解説した翻訳記事「asm.js:コンパイラのための低レベルかつ高度に最適化可能なJavaScriptのサブセット」を公開します。