WebAssembly
https://upload.wikimedia.org/wikipedia/commons/3/30/WebAssembly_Logo.png
「wasm」は「わずむ」と濁るっぽいmrsekut.icon
軽くまとめたもの
↓古い
概要
バイナリフォーマット
ブラウザ上で動作する低水準言語
Linear Assembly Bytecode ref 主要ブラウザベンダーが協働で使用策定
WebAssemblyをサポートした言語で書かれたコードをコンパイルしてWebブラウザ上で実行できる
ロードタイムを速くする
実行時間を速くするわけではない
のか?
論文
2017
Google, Mircrosoft, Apple, Mozillaの人の共著
関連
特徴
安全
ポータブル
高速
なぜ速いのか
軽量
バイナリ形式で配布する
textじゃなくてバイナリ形式な分、フェッチするデータ量が少なくて済む
起動が高速
事前にコンパイル
事前に型が決まるので高速
すべての命令が型を持つ
JSは動的型付けなので遅い
この過程で最適化ができる
実行時に、パース、コンパイルなどの処理をしない
動作が高速
ネイティブコード並の速さがでる
CPU機能の利用ができる
実際どのくらい速いのか
wasmはjsとできることは同じだが、速いのがうれしい
jsよりはやい
emscriptenの出力ファイルを実行するよりも速い
いまはおそい
Cの半分ぐらい
ネイティブコードはOSとかと絡むので、気をつけないといけないので
安全性が担保されている
だからこそ遅かったりする
UBは未定義ビヘイビア
これが起きないように気をつけてるから遅い
たとえばCでは配列の範囲外へのアクセス
module
配布する単位
オブジェクトファイルみたいな
関数のリスト、グローバル(変数?),テーブル、メモリなどの定義
import, exportが可能
classみたいなもの
ここからinstanceを作成する
moduleを実体化したもの
型システム
WASMモジュールの構造
のとこ
型にはそれぞれidが振られている
このidを用いて関数を型付けする
型は4種類
以下の組み合わせ
int, float
32bit, 64bit
オブジェクト、文字列は無理
論文のセクション4に書いてる
WebAssemblyバイナリ作成
wat
.wat
頑張れば手書きできる
線形のテキスト表現
.wasm
バイナリ
$ sexpr-wasm -o hoge.wasm hoge.wast
code:wast
(func $func (param i32 i32) (result i32) (local.get 0))
(type $check (func (param i32 i32) (result i32)))
(table funcref (elem $func))
(func (export "as-call_indirect-first") (result i32)
(block (result i32)
(call_indirect (type $check)
(loop (result i32) (i32.const 1)) (i32.const 2) (i32.const 0)
)
)
)
用途
JS以外の言語のプログラムをブラウザで実行したい
フロント、バックエンドを同じ言語で書ける
再利用とか、うれしい
現在はDOM操作ができない
重たい計算処理
暗号、圧縮、画像処理など
ゲームプラットフォームのブラウザ上への構築
モバイル、ゲーム機と並んでブラウザ向けにゲームをリリースできる
Cの既存の資産を生かす
圧縮、暗号、画像処理
CPUに依存する処理の高速化
LuaはC実装なのでwasmでコンパイルできた(?) 未読
JSとの共存
以下はできる
JSからWebAssemblyのロード、実行
WebAssemblyからJS関数の呼び出し
採用事例
eBayがwebのバーコードスキャナにwasmを採用した
wasmを含んだ幾つかの実装を並行に開発してwasm製のものが最速だったらしい
スキャンするのが速い、
製品全体をwasmで作った(?)
GC
Threads
複数のスレッドに対する処理、waitやwakeなどがまだ
DOM操作もまだ?
etc.
wasm-module
Rustで書いたWebAssemblyでもDOM操作をできるようにするやつ
wabt
JSファイルから読み込む
wasmファイルがブラウザ上でコンパイルして機械語に翻訳される
サイズが大きくなるとコンパイル時間も大きくなるが、従来のJSに比べれば高速
V8 v7.5からは、このコンパイル済みのモジュールがキャッシュされる
WebAssembly.compile
WebAssembly.instantiate(module)
moduleをインスタンス化したものを返す
WebAssemblyのコンパイル済みモジュールをキャッシュする
つまり、同じページに再び訪問したときは再コンパイルせず、キャッシュ済みのモジュールをロードする
誰かの実装してみた記事
関連ツール
以下を比較できる
C, C++のコード
wast
FireFox右上の三角をクリック
Cからwasmを作って実際にブラウザで実行するところまでできる wasmのplayground
JSとwasmを実行して比較する
サイドバーから選んで「run」する
フィボナッチとか良い感じに2倍くらい差が出る
C, Rust, AssemblyScript対応のオンラインIDE
「Build」した後に「Run」
つまりコンパイルしてwasmを吐けるビジュアルプログラミング言語
実際にWasmが使われているWebService
Google Earth
wasmの分析
WebAssemblyコンパイラを自作する ref ファイルサイズ
rust vs go
rustだいぶちいさい
react, redux
他にも記事あるかも
RustでWebAssemblyを扱う
Advent Calendar
2019/7/26あたりに追加された未読記事
fetch()などを使って動的にロードする
関連書籍
資料
↑百萬石の記事を書き直したもの
https://youtu.be/Ga8P_buwXnw?t=3918
wasmはめちゃくちゃ速くなるわけではないが、JSと比較して処理速度のブレが小さくなる
ブラウザをまたいでも
実際に使われているケースでは、パフォーマンス目的と言うよりは、既存のC実装のライブラリをブラウザで使用したい、といったものが多い
参考
実際はJSよりそんな爆速になるわけではない、など
jsのfetch,parse,最適化など順番にwasmと比較していてわかりやすい
あどかれ