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