Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

パフォーマンス

実行ティア

zwasm は階層型実行を採用しています:

  1. インタープリタ: すべての関数はレジスタ IR として開始され、ディスパッチループで実行されます。起動が速く、コンパイルのオーバーヘッドがありません。
  2. JIT (ARM64/x86_64): ホットな関数は、呼び出し回数またはバックエッジ回数がしきい値を超えるとネイティブコードにコンパイルされます。

JIT が発動する条件

  • 呼び出しのしきい値: 同じ関数が約8回呼び出された後
  • バックエッジカウント: ホットなループは JIT をより早くトリガーします(ループの反復回数がしきい値にカウントされます)
  • 適応型: しきい値は関数の特性に基づいて調整されます

JIT コンパイルが完了すると、その関数への以降のすべての呼び出しはインタープリタをバイパスし、ネイティブマシンコードを直接実行します。

バイナリサイズとメモリ

指標
バイナリサイズ (ReleaseSafe)約 1.4 MB
ランタイムメモリ (fib ベンチマーク)約 3.5 MB RSS
wasmtime バイナリ(比較用)56.3 MB

zwasm は wasmtime の約1/40のサイズです。

ベンチマーク結果

Apple M4 Pro 上で zwasm を wasmtime 41.0.1、Bun 1.3.8、Node v24.13.0 と比較した代表的なベンチマーク。 29 個中 16 個のベンチマークで wasmtime と同等以上の性能。29 個中 25 個が 1.5 倍以内。

ベンチマークzwasmwasmtimeBunNode
nqueens(8)2 ms5 ms14 ms23 ms
nbody(1M)22 ms22 ms32 ms36 ms
gcd(12K,67K)2 ms5 ms14 ms23 ms
tak(24,16,8)5 ms9 ms17 ms29 ms
sieve(1M)5 ms7 ms17 ms29 ms
fib(35)46 ms51 ms36 ms52 ms
st_fib2900 ms674 ms353 ms389 ms

メモリ使用量は wasmtime の 3〜4 分の 1、Bun/Node の 8〜10 分の 1 です。

全結果(29 ベンチマーク): bench/runtime_comparison.yaml

SIMD パフォーマンス

SIMD 操作は機能的に完全です(256 オペコード、仕様テスト 100%)が、レジスタ IR や JIT ではなくスタックインタプリタで実行されます。その結果、SIMD 実行は wasmtime の約 22 倍遅くなります。改善計画: レジスタ IR の v128 拡張、その後選択的な JIT NEON/SSE エミッション。

ベンチマーク手法

すべての測定は hyperfine を使用し、ReleaseSafe ビルドで行っています:

# クイックチェック(1回実行、ウォームアップなし)
bash bench/run_bench.sh --quick

# 完全な測定(3回実行、1回ウォームアップ)
bash bench/run_bench.sh

# 履歴に記録
bash bench/record.sh --id="X" --reason="description"

ベンチマークレイヤー

レイヤー説明
WAT micro5手書き: fib, tak, sieve, nbody, nqueens
TinyGo11TinyGo コンパイラ出力: 同じアルゴリズム + 文字列操作
Shootout5Sightglass shootout スイート (WASI)
Real-world6Rust, C, C++ を Wasm にコンパイル (行列、数学、文字列、ソート)
GC2GC プロポーザル: 構造体アロケーション、木の走査

CI によるリグレッション検出

PR は自動的にパフォーマンスリグレッションがチェックされます:

  • 6つの代表的なベンチマークがベースブランチと PR ブランチの両方で実行されます
  • いずれかのベンチマークが20%以上リグレッションした場合、失敗となります
  • 同一ランナーにより公平な比較が保証されます

パフォーマンスのヒント

  • ReleaseSafe: 本番環境では必ず使用してください。Debug は5〜10倍遅くなります。
  • ホットな関数: 頻繁に呼び出される関数は自動的に JIT コンパイルされます。
  • Fuel 制限: --fuel は命令ごとにオーバーヘッドが加わります。信頼できないコードにのみ使用してください。
  • メモリ: リニアメモリを持つ Wasm モジュールはガードページを割り当てます。初期 RSS はモジュールサイズに関係なく約 3.5 MB です。