dcodeIO/webassembly: A minimal toolkit and runtime to produce and run WebAssembly modules.内のツールチェーンを使用してzlibをビルドしてみました。
dcodeIO/webassemblyとは
曰く、実験的でミニマルなツールキットとランタイムを持っていて、cのファイルをwasmにコンパイルして実行できますとのこと。malloc
とか最低限欲しいものは入っているので、ちょっとしたプログラムを書きたいがemscripten使うほどでもないときに便利です。
zlibをビルドする
サンプルレポジトリを作ったのでgit clone
してきてビルドします。Windows Subsystem for Linux, macOS High Sierraで動作確認をしています。
$ git clone https://github.com/ukyo/zlib-wasm-without-emscripten-sample.git
$ cd zlib-wasm-without-emsripten-sample
$ npm install
$ npm run build
ビルドスクリプトはwebassembly/build.js at master · dcodeIO/webassemblyを参考にして組んでみました(流れは以下図を参照)。
<stdio.h>
がないとか言われてちょっとハマったりしましたが、ヘッダーファイルをでっち上げて-isystem path/to/include
して回避しました。importObjectに入れる関数を定義したい場合は、import.hのようなヘッダーファイルだけ作るとインポートする扱いになるみたいです。
ベンチマーク
wasm, pako, nodeのzlibで比較。生のdeflate, inflateでベンチマークを取ってみました。
- Node: v8.9.1
- OS: MacBook Pro High Sierra
- CPU: Intel Core i5 2.4GHz
- Memory: 16GB
$ npm run bench
## lorem_1mb.txt size: 1000205
wasm x 9.61 ops/sec ±4.48% (27 runs sampled)
pako x 8.70 ops/sec ±2.26% (25 runs sampled)
native x 15.21 ops/sec ±3.15% (41 runs sampled)
Deflate: Fastest is native
## deflated lorem_1mb.txt size: 257012
wasm x 120 ops/sec ±10.26% (60 runs sampled)
pako x 106 ops/sec ±8.56% (67 runs sampled)
native x 211 ops/sec ±2.68% (74 runs sampled)
Inflate: Fastest is native
なんとかpakoに勝ててますね(このくらいの規模だとさすがにJavaScriptには勝てるらしい)。ちなみにファイルサイズは60.4KB(wasm) + 3.6KB(js)。wasmのほうはgzipして28KBくらいなので、かなり許せる範囲じゃないでしょうか。
まとめ
Emscriptenとか使わずにdcodeIO/webassembly内のツールチェーンでzlibをwasmにコンパイルしてみました。emsdkに環境を汚染されずに、npm i && npm run build
程度でビルドできるのが良いですね。