2013-04-19

asm.jsを手書きしつつフィボナッチで速度比較をしてみる

asm.jsを触ってみたので所感など。

asm.jsはJavaScriptのサブセットで、限られた型しか使えないが高速に動作する言語との事。とりあえずどの程度速くなるのか、計算量が多くなるfibonacciの実装で試してみた。参考資料はasm.jsの仕様ぐらいしか無かったのでこれを見ながら。

で、実際に書いてみると型がゆるゆるなJavaScriptのイメージは脆くも崩れ去り、厳格な型チェックの世界である事がわかった。コンパイル言語を書いている時の頭に切り換えないと、コンパイルエラーと延々格闘する事になる。まずはasm.jsのコードは次の形式で、module exportする。
function create_my_asm_module(stdlib, foreign, heap) {
  "use asm";

  function hoge() {...}
  function fuga() {...}

  return {
    hoge: hoge,
    fuga: fuga
  }
}
asm_my_modules = create_my_asm_module(window);
関数の書き型にも決まりがあり、次の順番で記述する必要がある。
function hoge(fuga) {
  // 1)パラメータの型指定
  // 2)変数の初期化
  // 3)処理
  // 4)return句
}
次にasm.jsで書く関数の引数の型、戻り値の型を決める。引数の型はParameter Type Annotationsで記述する。
  
function calc_tax_included_price(price, tax_rate) {
    price = price|0;      // priceはint
    tax_rate = +tax_rate; // tax_rateはdouble

    //略
}
仕様にはintとdoubleしか無いのでどちらかとなる。
関数の戻り値はReturn Type Annotationsで記述する。関数内にreturnが複数個ある場合、それぞれの箇所でreturnの型が異なるとコンパイルできない。
  
return +d;  // double
return i|0; // signed int
return 1;   // double
return;     // void
で、実際にフィボナッチが動くコードと実行結果が以下。実行はAuroraバージョン22.0a2。

asm.jsの方が速いのがわかる。といってもこの程度ならまだしも、実際に高速化したい処理を手でasm.jsで書くのは正直厳しいという印象。githubで "use asm"しているコードを探したら行列演算ライブラリが出てきましたが、ヒープ操作している所が全く読めなくてやばい。


このエントリーをはてなブックマークに追加