asm.js
概要
2013年ごろ
JSの文法に対する後方互換性がある
ちょっと頑張ればasm.jsを直接手書きすることもできる
これが高速さの理由
高速実行を目指して設計
型の恩恵もある
Firefox 22 (2013/6/25公開)からサポート
Links
更新が止まっている
変数、式、関数の型が静的解析可能
数値計算に特化
オブジェクトに関する操作ができない
メソッド呼び出しなど
利用できるコレクション型は Typed Array
のみ
速い
GCしない
>ガベージコレクタは不要となる。メモリは大きな型つき配列ヒープの中で、mallocとfreeのような機能によってマニュアルで管理されるようになるからだ。 ref
DOM操作は速くならない
計算処理的な部分が速くなる
OdionMonkey
asm..jsとの組み合わせでこのベンチマーク
ネイティブの2倍程度の実行時間
対応 いつの?
firefox
chrome
edge
Node.js
インタプリタ的に動作する
構文解析してASTを作って、VM用のバイトコードに変換する
バイトコードはスタックマシンを操作するコードの様なもの
例
vmgetarg 0
getarg 1
getarg 2
mul
add
return
retrval
バイトコードをひとつずつ取ってきて、switch文を通して各命令を実行する関数が呼ばれる
型がわからないとネイティブコードは冗長になる
たとえば、IntelのPCUは20種類以上の加算の命令がある
データ型とデータの保存場所によって使用する命令が異なるから
型が決まっていると、命令は一つで済む
決まっていない場合、ひとつずつチェックしないといけない
実行時間が遅くなる
コンパイルまでの過程
ネイティブコードはメモリ上へ展開される
これとは別にあるJSの関数やasm.jsの標準ライブラリとのリンクが行われる
失敗するパターン
意味解析で失敗
型エラーが起こった時
リンクで失敗
メソッドの呼び出し、JSにExportできない種類のデータを引数に指定した関数呼び出しを行った場合
モジュール単位でコンパイル
js// ↓これが一つのmoduleになる
function AddFunctions(){
"use asm";
// 関数を宣言
function add1(value){
value = value | 0; // 変数の宣言. int型
var result = 0;
result = (value + 1) | 0; // 加算の結果はintishになるので、intにキャスト
return result;
}
// 関数表の宣言
return {
add1: add1
}
}
ヒープを利用する
asm.jsで定義できる関数は数値演算しか出来ない
文字列やオブジェクトを用いたコードは使えない
ヒープを使う
Cが文字列を数値の配列として扱っているアイディアを使う
コード例
部分的にだけどこんなの
jsfor(;(HEAP[i << 0 >> 0] | 0) != 0; i = i + 1 | 0){
buffer[i << 0 >> 0] = ((buffer[i << 0 >> 0] | 0) + key) | 0;
}
あくまでもJSの記法で型アノテーションをする
同値として解釈できるような冗長なJSを書いている感じ
asm.js処理系には型だとわかるが、それ以外の処理系にはちょっと冗長なJSコードに見える
例
+hoge
はdouble
hoge | 0
はint
f(hoge)
はfloat
型を付けられるもの
変数
関数の引数
int
か double
関数の戻り値
double
, signed
, float
, void
型の継承関係
ゲームエンジンによるサポート
UE, Unity
asm.jsの課題
ファイルサイズ増大による
通信量の増加
構文解析時間の増加
asm.jsを拡張するためには、まずJSを拡張しないといけない
#??
関連
並列化
データを纏めて処理
参考