asm.js:コンパイラのための低レベルかつ高度に最適化可能なJavaScriptのサブセット
JavaScriptのサブセットとして静的型付け言語を定義し、事前コンパイルを可能にすることでJavaScriptの実行速度を劇的に改善しようというasm.jsの概要を、1つ前の記事で調べました。
まだasm.jsの情報は少ないのですが、その中でも分かりやすくまとまった記事がDevon Govett氏のブログBADASS JAVASCRIPTのエントリ「asm.js: A Low Level, Highly Optimizable Subset of JavaScript for Compilers」です。
Govett氏に翻訳の許可を得たので、翻訳記事として掲載します。
asm.js:コンパイラのための低レベルかつ高度に最適化可能なJavaScriptのサブセット
asm.js: A Low Level, Highly Optimizable Subset of JavaScript for Compilers
MozillaのDavid Herman、Luke WagnerそしてAlon Zakai(およびEmscrptenの開発者)らは、asm.js仕様策定を続けてきた。目指したのは、高度に最適化可能なJavaScriptのサブセットだ。それはEmscriptenのようなコンパイラを主なターゲットとして設計されたが、とくに優れているのは、絞り込まれたサブセットのおかげで既存のJavaScriptの文法に対する後方互換性があることだ。つまりこれはasm.jsコードが以前のブラウザでも実行できるということを意味する。ただしそのときはJavaScriptエンジンの拡張による最適化の効果は得られないが。
asm.jsを使うには、ファイルか個別の関数の先頭に“use asm;”と記述する。ちょうど“use strict;”でstrict modeを宣言するのと同じだ。これによって事前最適化コンパイラ(ahead-of-time(AOT) optimizing complier)が起動し、型アノテーション(type annotations)を探索したうえでコードが実際に最適化可能かどうかを確認する。
型アノテーションは面白い記法で、TypeScriptなどの試みと比べると、通常のJavaScriptとの後方互換性がある点でまったく異なるものだ。asm.jsは既存のJavaScriptの演算記号(operator)を型のヒントとして用いる。例えば“+a”は変数を倍精度型(double)としてアノテートし、“a|0”は整数型(integer)とする。
与えられたコードがasm.js対応のものだとJavaScriptエンジンが判断すると、事前コンパイルが有効となり、あとになって実行時型チェック、ガベージコレクション、脱最適化(deoptimizing)へと脱出するような心配はなくなる(新野注:このdeoptimizationとは、恐らくV8のJITのような実行時コンパイラが生成コードの最適化に失敗したときに、元のインタプリタ実行に戻ることをdeoptimizationへbail outすると表現していることを指しているのではないかと思います)。
このとき、ガベージコレクタは不要となる。メモリは大きな型つき配列ヒープの中で、mallocとfreeのような機能によってマニュアルで管理されるようになるからだ。これらすべては事前に行われ、実行時のJavaScriptエンジンの仕事を減らし、プログラムの実行速度の向上に明確に貢献することだろう。そしてブラウザ内で実行されるJavaScriptプログラムの実行速度をよりネイティブコードへと近づけてくれる。プラットフォームとしてこれは重要なことだ。
もしこんな書き方はウンザリだと言われれば同意せざるを得ないが、考え得る最悪の構文とまではいかないだろう。これは実際のところ人がコードを書くことをターゲットにしておらず、Emscripten、Mandreel、LLJS、あるいはTypeScriptなどを想定している。これらのコンパイラで、Cのような既存言語やLLJSやTypeScriptのような新言語から、巧妙に後方互換性を保ちつつもそれほど明確ではない型アノテーション(付きのasm.jsコード)を生成できる。
Emscriptenはすでにasm.jsに対応したコードを生成できるようになっており、それがこのプロジェクトにはずみをつけつつある。また、Firefoxは近いうちにasm.jsに最適化したコンパイラを実現するつもりであり、ベンチマークは実に驚異的なものとなっている。
JavaScriptアプリケーションの性能にとっては、まさにエキサイティングな状況であり、asm.jsはそれを助けている。
これはGoogleのNative Client(NaCl)プロジェクトに対するMozillaからの返答だといえるだろう。NaClは、コンパイルされたコードをWebブラウザのサンドボックス環境下で実行するものだ。asm.jsはJavaScriptのサブセットなので後方互換性を持っており、私はこれが、Webにおける高度な最適化をめぐるなかで勝者となる大きな要素ではないかと見ている。NaClは現時点で誰もが利用できるものではないが、asm.jsはまだ正式にサポートをしていないJavaScriptエンジンでさえもすでに利用可能なのだから。
興味のある方は、ぜひasm.js仕様や、Github上にあるDavid Hermanのasm.js validatorのプロトタイプ実装(JavaScriptで書かれている!)、そしてEmscriptenの開発者Alon ZakaiのEmscripten、asm.jsとその将来に関するプレゼンテーションなどをチェックしてほしい。私は彼らの開発がどうなるのか、先行きを非常に楽しみにしている。
(追記:3/27 9:20 原文の第四パラグラフに当たる部分の訳を一部手直ししました)
あわせて読みたい
Software-Defined Networkに関してガートナーが言っていること。「ビジネスのアジリティを提供する」「ネットワーク仮想化と同一視するべきではない」
≪前の記事
JavaScriptの実行速度を劇的に改善するasm.jsの特徴は、CやC++のような言語をJavaScriptのサブセットで記述すること