2017/12/19 5:55 pm
Webでより高速なWebアプリケーションを実行するための仕組みとして注目されているのがWebAssemblyです。バイナリファイルであり、あらかじめコンパイルされていることでソースコードを簡単に見られてしまうJavaScriptの欠点を補うことができます。
現在、CやC++で書くことが多いWebAssemblyですが、Rustも着実に対応が進んでいます。ついに Rust単体でWebAssemblyをコンパイルする(Emscripten無し) にあるようにRustだけでWebAssembly向けにコンパイルができるようになりました。
今回はそちらのレビューになります。
RustはC/C++に比べると分かりやすい言語だと思います。型推測もあり、スクリプト言語のように書けます。今回はJavaScriptとの速度比較用に、以下のようなコードにしてみました。時間をかけるため、あえてループを繰り返しています。
| #[no_mangle] | |
| pub fn sum(a: i32) -> i32 { | |
| let mut total = 0; | |
| for x in 0..a { | |
| total += x; | |
| for y in 0..a { | |
| total += y; | |
| } | |
| } | |
| total | |
| } |
これをコンパイルします。
| rustc +nightly –target wasm32-unknown-unknown -O main.rs –crate-type=cdylib |
その結果 main.wasm というファイルが生成されます。
WebAssemblyは script タグで呼び出せる訳ではありません。Ajaxで取得する必要があります。以下の処理で sum という関数が使えるようになります。
| var sum = null; | |
| fetch('main.wasm') | |
| .then((response) => response.arrayBuffer()) | |
| .then((bytes) => WebAssembly.instantiate(bytes, {})) | |
| .then((results) => { | |
| const instance = results.instance; | |
| sum = instance.exports.sum; | |
| }); |
sum 自体は Native Code と判断されます。実行は普通の関数と変わりません。
| > sum(10) | |
| <- 495 |
JavaScriptでは以下のようなコードで試しました。
| total = 0; | |
| for (var x = 0; x < i; x++) { | |
| total += x; | |
| for (var y = 0; y < i; y++) { | |
| total += y; | |
| } | |
| } | |
| console.log(total); |
それぞれ3回繰り返した平均値です(単位は ms)。
| 回数 | Rust | JavaScript |
|---|---|---|
| 100 | 190 | 513 |
| 1,000 | 165 | 3979 |
| 2,000 | 163 | 36593 |
| 5,000 | 172 | 337251 |
| 10,000 | 209 | 1427188 |
WebAssemblyの実行結果は回数に殆ど関係しませんでした。10,000回繰り返した時にも275/176/177msといった数字で、もっと回数の少ない時と変わりません。逆にJavaScriptは処理回数によってリニアに処理時間が延びている印象です。
現状のWebAssemblyはDOMやWeb API、GCに対応していません。そのため利用範囲が限られてしまうでしょう。将来的にはこれらのAPIにも対応が予定されています。
Rust自体は学習しやすい言語だと思います。それによって現状のWebを高速化できるので今後に期待した技術です。現状についてはJavaScriptから呼び出される補助的な技術ですが、将来的にはC/C++/Rustをはじめ、多くの言語でWebアプリケーションが開発できるようになるでしょう。
作成者: moongift
カテゴリー: HTML5
タグ: WebAssembly
Mobile Site | Full Site
Get a free blog at WordPress.com Theme: WordPress Mobile Edition by Alex King.