ぶていのログでぶログ

思い出したが吉日

Wasmer CLIでruby.wasmを試してみる

reddish-shellに使えるか技術検証のためにruby.wasmを試してみる。 最終的にはRustに組み込むことになると思うのでランタイムにWasmer - The Universal WebAssembly Runtimeを使う。 WasmerにはCLIがあるのでそれを使ってみる。 Wasmerのインストール手順は公式ドキュメントに書いてあるが、私はasdfを使っているのでそれ経由でインストールした。

❯ asdf plugin-add wasmer
❯ asdf install wasmer latest
❯ asdf global wasmer latest
❯ wasmer --version
wasmer 2.3.0

ruby.wasmは公式リポジトリのReleaseページにある。 今時点では ruby-head-wasm32-unknown-wasi-full.tar.gz みたいなバイナリをダウンロード して展開すればよさそう。

❯ tar xvf ~/Downloads/ruby-head-wasm32-unknown-wasi-full.tar.gz
❯ ls -lah head-wasm32-unknown-wasi-full/ head-wasm32-unknown-wasi-full/usr/local/bin/ruby
.rwxr-xr-x buty4649 buty4649  12 MB Sat Oct  8 00:25:30 2022  head-wasm32-unknown-wasi-full/usr/local/bin/ruby

head-wasm32-unknown-wasi-full/:
drwxr-xr-x buty4649 buty4649 4.0 KB Sat Oct  8 00:25:30 2022  .
drwxr-xr-x buty4649 buty4649 4.0 KB Sun Oct  9 14:38:09 2022  ..
drwxr-xr-x buty4649 buty4649 4.0 KB Sat Oct  8 00:25:30 2022  usr

tarballに含まれる /usr/local/bin/ruby がwasmライブラリになっている。

❯ file head-wasm32-unknown-wasi-full/usr/local/bin/ruby
head-wasm32-unknown-wasi-full/usr/local/bin/ruby: WebAssembly (wasm) binary module version 0x1 (MVP)

Wasmer CLIを使って起動してみる。 --mapdirオプションを使って $(pwd)/srcとtarballの中にあるusrディレクトリは以下をマップする必要がある。

❯ mkdir src
❯ echo "puts 'Hello'" > src/my_app.rb
❯ time wasmer run --mapdir /src::./src --mapdir /usr::head-wasm32-unknown-wasi-full/usr head-wasm32-unknown-wasi-full/usr/local/bin/ruby -- /src/my_app.rb
Hello

________________________________________________________
Executed in  219.70 millis    fish           external
   usr time  140.84 millis  118.00 micros  140.72 millis
   sys time   67.46 millis  109.00 micros   67.35 millis

感想

WASM層を挟むことで様々なプラットフォームで動いて便利そう。 ネイティブバイナリと比較してもそこそこの速度で動いているし私の用途としてもあっていそう。

#  ネイティブバイナリの実行速度
❯ time ruby src/my_app.rb
Hello

________________________________________________________
Executed in   68.99 millis    fish           external
   usr time   46.88 millis  129.00 micros   46.75 millis
   sys time   10.39 millis  129.00 micros   10.26 millis

しかしながら、今時点ではバイナリ以外のファイルをマウントしないといけないので私のユースケースではミスマッチかなぁという印象だった。