WebAssembyについて調べたことをまとめてみた


Rustを勉強する中で出会ったWebAssemblyという技術を気になったので調べてみました。

WebAssembly(WASM)とは?

ウェブブラウザーで動作し、新たな機能と大幅なパフォーマンス向上を提供する新しい種類のコード。基本的に直接記述ではなく、C、C++、Rust 等の低水準の言語にとって効果的なコンパイル対象となるように設計されている。
実行時にパースやバイナリーコードへの変換処理が不要なため、ウェブ上で動作するクライアントアプリで従来は実現できなかった、ネイティブ水準の速度で複数の言語で記述されたコードをウェブ上で動作させる

WebAssembly対応言語

・C
・C++
・Rust1.14以降
・Go1.11以降
・Kotlin/Native0.4以降

WebAssemblyの登場した背景

JavaScript も実行速度が求められるようになった

JavaScript は実行速度が遅い
動的型付け言語のため、事前にコンパイルができず、インタプリタにより逐次的に機械語に翻訳する
インタプリタは、文字列を解釈し、抽象構文木 (AST: Abstract Sytactic Tree) を作成する等のオーバーヘッドが生じる

JIT コンパイラ (実行時コンパイラ) による高速化

JIT は Just In Time の略
JIT コンパイラは、実行環境に依存しない中間コードを、ソフトウェアの実行時に機械語にコンパイルする
具体的には、しばらくインタープリタを用いて動作させた後、得られた統計情報から型を推定し、必要に応じてネイティブコードに変換する

問題点

型の推定用に統計情報が必要なため、高速に動作するまでに時間が必要
型の推定に失敗することがある

asm.js の登場

JavaScript のサブセット
JavaScript を特定の制約に従って記述することで、型を明確にして AOT コンパイルできるようにする
AOT は Ahead-Of-Time(実行前コンパイル)を意味する

問題点

ファイルサイズの増大による通信量の増加
ファイルサイズの増大による構文解析の時間の増加

そしてWebAssembly (Wasm) へ

WASMとJavascriptの関係性

WebAssembly は JavaScript と異なる言語だが、その置き換えを意図していない。その代わり、JavaScript の足りない所を補填して併用し、ウェブ開発者に双方の以下のような利益を提供する事を狙っている(DOMのアクセスにWASMは制限があるので単純に置き換える事ができない)
JavaScript は高水準の言語であり、ウェブアプリケーションを作る上で十分な柔軟性と表現力を持っている。そして多くの利点 — 動的型付け言語である、コンパイルが必須でない、パワフルなフレームワーク、ライブラリやツールを提供する豊富な土壌等を持っている。

WebAssembly はネイティブに近いパフォーマンスで動作して、C++ や Rust のような低水準のメモリー管理を行う言語がウェブ上で動作するようコンパイルされる対象となる、コンパクトなバイナリー形式を持つ低水準なアセンブリに似た言語 (WebAssembly は将来的にGCによるメモリー管理を行う言語をサポートする 高レベルの目標 を持っている)。

WASMはなぜ早いのか?

WebAssemblyはポータブルなスタックマシンであり、既存のウェブブラウザで広く用いられているJavaScriptと比べ、構文解析と実行が高速になるよう設計されている。

CPUの活用
asm.jsはJavaScriptとして処理できる形式でモジュールとその関数本体を定義していたため、その能力はJavascriptの表現できることに限定されていた。
一方でWebAssemblyは仮想的なハードウェアで動く低水準な命令の集まりとしてモジュールを定義されている。
これによりJavaScriptの表現能力に制限されず、CPUの機能をより十全に利用すること出来る。
起動の高速化
抽象構文木がバイナリ形式で与えられているおかげで、ネイティブコードを出力するために必要な処理の字句解析と構文解析の大半を省き、起動の高速化が可能となっている

普通のJavascriptだとブラウザの総実行時間の15-20%をパースに使っているらしい...

まとめ

以上、WASMについてまとめたことをまとめました。とても魅力的な機能のように思いますが、以下を見る限りまだブラウザなどによっては使えない機能が多く発展途上の技術であるとも言えると思います
https://webassembly.org/roadmap/