はじめに
WASMとはWebAssemblyのこと。最近のブラウザで実行可能なバイナリデータです。
そもそもJavascript(Node.js)は軽量言語にしては速いです。なので通常の用途において、WebAssemblyに置き換えるケースというのはあまり多くないでしょうが、単純な計算を繰り返し実行する必要があり、かつその速度を改善したい場合には、有効な手段と言えるでしょう。
今回はJavaScript(Node.js)とWASMで同じ関数を実行し処理速度を比較してみます。
ブラウザでも使えますが、速度比較の環境を作るのがめんどくさかったのでNode.jsと比較します(たぶんNode.jsの方がブラウザより速いでしょうから、WASM>Node.jsならWASM>ブラウザでしょう)。
WASMのつくりかた
wasm-pack + Rustで作ります(targetはnodejs)
実行する関数
フィボナッチ関数の第x項を求める関数です。メモ化などしていない素朴な実装。
第30項までを単純なループで実行し、その所要時間を比較します。
// Rust
pub fn fibo(x: u32) -> u32 {
if x < 3 {
return 1;
}
fibo(x - 1) + fibo(x - 2)
}
//JavaScript
const fiboJs = (idx) => {
if (idx < 3) return 1
return fiboJs(idx - 1) + fiboJs(idx - 2)
}
結果
# WASM
finish wasm 8.863149046897888
finish wasm, including init 13.06051504611969
# JavaScript
finish js 18.82902693748474
結論
- 単純な計算速度の比較だけならWASMが2倍以上速い
- WASMの初期化で多少のオーバーヘッドが発生する(それでも今回の処理ではWASMの方が速い)
おわりに
- 関数の実行回数が増えれば増えるほどWASMが有利(WASMの初期化のロスの影響が小さくなるので)