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.2 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 (v128) 命令はネイティブの NEON (ARM64, 253/256 命令) および SSE (x86_64, 244/256 命令) に JIT コンパイルされます。v128 値はレジスタファイル内で 64 ビット×2 の分割格納方式を採用しています。

ベンチマークzwasm スカラーzwasm SIMDwasmtime SIMDSIMD 高速化
image_blend (128x128)73 ms16 ms12 ms4.7x
matrix_mul (16x16)10 ms6 ms8 ms1.6x
byte_search (64KB)52 ms43 ms5 ms1.2x
dot_product (4096)142 ms190 ms15 ms0.75x

matrix_mul は wasmtime を上回り、image_blend は 1.3 倍差でほぼ互角です。dot_product は v128.load の多いループで分割格納のオーバーヘッドにより低下しています。

コンパイラ生成の SIMD コード (C -msimd128) では、i16x8.replace_lane 等のパターンにより より大きな差が生じます。今後の改善: 連続 v128 レジスタ格納 (W37) によるオーバーヘッド解消。

全データ: bench/simd_comparison.yaml

ベンチマーク手法

すべての測定は 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 プロポーザル: 構造体アロケーション、木の走査
SIMD10WAT マイクロ (4) + C -msimd128 実世界 (5)、スカラー/SIMD

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

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

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

パフォーマンスのヒント

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