2026年におけるWebAssemblyランタイムのパフォーマンス
Performance of WebAssembly Runtimes in 2026 (00f.net)
要約
この記事は、2019年から続くWebAssembly(Wasm)ランタイムのパフォーマンス比較の最新版です。2024年、2025年、2026年にリリースされたランタイム上で、同じC言語の暗号ライブラリ(libsodium)をコンパイルして実行し、その実行速度をネイティブコードと比較しています。全体として、ランタイムは着実に改善していますが、特に`wide_arithmetic`命令セットのサポートがパフォーマンスに大きな影響を与えることが示されています。WasmerとWasmtimeが`wide_arithmetic`をサポートした場合に最も高速な結果を示しました。
全文翻訳
2026年におけるWebAssemblyランタイムのパフォーマンス
WebAssemblyランタイムは高速化しているのかを知りたかった。
これは、2019年、2021年、および2023年の以前のlibsodium WebAssemblyベンチマークのフォローアップです。
「最新バージョンがマイクロベンチマークでネイティブコードを上回るか?」でもなく、「どのランタイムが最も見栄えの良いベンチマークチャートを持っているか?」でもなく、もっと退屈で有用なこと、つまり:
同じC暗号コードをWebAssemblyにコンパイルし、最新のランタイム、1年前のランタイム、2年前のランタイムで実行した場合、実際に改善されているのか?
そこで、2024年6月頃、2025年6月頃、2026年6月頃にリリースされたWebAssemblyランタイムでlibsodiumをベンチマークしました。
短いバージョン:
wasmerが最高のパフォーマンスですが、WAVM、WAMR、Wasmtimeも僅差です。WAVMは最高のオプティマイザーを持っており、ベースラインのポータブルWebAssemblyから非常に高速なコードを生成できます。- 新しいWebAssembly
wide_arithmetic命令は、ランタイムがサポートしている場合、暗号コードにとって大きな意味があります。
計測したもの
テストプログラムはlibsodiumのベンチマークスイートで、libsodiumのコミット 8e3be8615ba6adcd7babaecf5e76f516890ba5fb からビルドしました。
ネイティブのベースラインといくつかのWebAssemblyバリアントをビルドしました:
- ネイティブ x86-64、ローカルCPUターゲットでZigを使用してコンパイル
- プレーンWebAssembly
lime1を使用したWebAssemblylime1とsimd128を使用したWebAssemblylime1、simd128、およびwide_arithmeticを使用したWebAssembly
ネイティブリファレンスの場合、libsodiumは -Dcpu=native でビルドされました。wasm2c の場合、生成されたCは zig cc -O3 -march=native でコンパイルされました。
WAMR では、AOTモードを使用しました:wamrc は各 .wasm ファイルを .aot ファイルにコンパイルし、iwasm は結果のAOTファイルを実行しました。wamrc は --cpu=native を受け付けないため、--target=x86_64 --cpu=x86-64-v4 --opt-level=3 を使用しました。これはホストが利用可能なx86-64機能レベルと一致し、これらのモジュールをコンパイルできたWAMRのバージョン全体で機能します。
ネイティブコマンドは次のとおりでした:
zig build -Denable_benchmarks -Doptimize=ReleaseFast -Dcpu=native -Diterations=3
WebAssemblyコマンドは同じ形状で、wasm32-wasi ターゲットと機能固有のCPU文字列を使用しました:
zig build -Denable_benchmarks -Dtarget=wasm32-wasi -Doptimize=ReleaseFast -Diterations=3
zig build -Denable_benchmarks -Dtarget=wasm32-wasi -Doptimize=ReleaseFast -Dcpu=lime1 -Diterations=3
zig build -Denable_benchmarks -Dtarget=wasm32-wasi -Doptimize=ReleaseFast -Dcpu=lime1+simd128 -Diterations=3
zig build -Denable_benchmarks -Dtarget=wasm32-wasi -Doptimize=ReleaseFast -Dcpu=lime1+simd128+wide_arithmetic -Diterations=3
ホストは、12コア24スレッドのAMD Ryzen AI 9 HX 470でした。CPUブーストは無効化され、最大CPU周波数は2 GHzでした。OSはLinux 7.1.0-rc7、Zigは 0.17.0-dev.948+e949341b7 でした。
以下の数値は、ネイティブビルドに対するベンチマークごとの遅延の幾何平均です。値が小さいほど良いことを意味します。2.0 という値は、このマシンで「ネイティブの2倍遅い」ことを意味します。
ITERATIONS=3 を使用したため、非常に小さいlibsodiumテストはノイズが多く、量子化されています。ゼロ時間を報告した行は集計から除外されました。
バージョン
WAVM を除くすべてのランタイムについて、2026年6月23日に利用可能な最新の安定リリースに加え、約1年前と約2年前の安定リリースを使用しました。
| ランタイム | 2024 | 2025 | 2026 |
|---|---|---|---|
Bun | 1.1.16 | 1.2.17 | 1.3.14 |
Node | 22.3.0 | 24.2.0 | 26.3.1 |
WAMR | 2.1.0 | 2.3.1 | 2.4.4 |
WABT wasm2c | 1.0.35 | 1.0.37 | 1.0.41 |
WasmEdge | 0.14.0 | 0.14.1 | 0.17.0 |
Wasmer | 4.3.2 | 6.0.1 | 7.1.0 |
Wasmtime | 22.0.0 | 34.0.0 | 46.0.0 |
WAVM | n/a | n/a | nightly/2026-04-05 |
Wazero | 1.7.3 | 1.9.0 | 1.12.0 |
WAVM は歴史的な比較が難しいです。利用可能な古いナイトリービルドは、2024年と2025年のスロットの両方で2022年のバイナリに収束しましたが、そのバイナリはこのマシンでは実行を拒否しました。2026年のナイトリービルドのみを保持しました。
WAMR 2.1.0(選択された2024年リリース)は正常にインストールされましたが、そのAOTコンパイラはこれらのZig生成モジュールで invalid WASM stack data type というエラーで失敗しました。マトリックスにはバージョンを含めましたが、集計には含めませんでした。
ベースラインWebAssembly
これは、lime1、SIMD、またはワイド算術を使用しない、プレーンなWebAssemblyビルドです。
[画像: ベースラインWebAssemblyのリリース年ごとの遅延]
普遍的なトレンドはありません。
Wasmtime は着実に改善しました:2024年はネイティブの2.67倍、2025年は2.54倍、2026年は2.41倍でした。毎年高速化しており、その改善はノイズの上に、10分の1単位で着実に現れています。
Node もゆっくりと改善しました。ネイティブの8.60倍から7.95倍になりました。
Wazero はほぼ横ばいでした:4.84倍、4.70倍、4.72倍。2年間で実質的な動きはありませんでした。
WAMR はAOTモードで2025年には既に高速で、2026年もそのままでした:ネイティブの1.59倍、次に1.57倍で、このベンチマークのノイズの範囲内でした。WAMR 2.1.0 がこれらのモジュールをコンパイルできなかったため、完全な2024年のWAMRの数値はありません。
Wasmer はテストした2025年リリースで後退し、その後2026年に回復しました。2026年のベースラインは2024年をわずかに上回る程度でした。
wasm2c は2026年に控えめに改善しました。デプロイメントモデルで事前にネイティブCへの変換が許容される場合、依然として最良の選択肢の1つです。
Bun は例外です。2024年と2025年の結果は大きく遅れていましたが、2026年の結果は2025年の結果よりも約3倍高速でした。このワークロードではまだ Node よりも遅いですが、方向性は素晴らしいです。
WasmEdge も高速ですが、コマンドラインの動作が重要になるほど変更されました。最初の 0.17.0 の実行では、コンパイル済みモジュールで誤ってインタープリターモードが使用され、壊滅的に遅いように見えました。コンパイル済みモジュールを --run-mode=aot で実行することで修正されました:2026年のベースラインはネイティブの1.74倍で、2024年と2025年のベースライン結果の間に位置しました。
年ごとの最良サポートビルド
ベースラインテーブルは、すべての場所で同じWebAssemblyターゲットを比較するため有用です。
しかし、独自のデプロイメント用のランタイムを選択する場合、そのランタイムが実際に実行できる最速のビルドを気にするでしょう。
そのため、各ランタイムと年について、サポートされているビルド(ベースライン、lime1、lime1+simd128、およびlime1+simd128+wide_arithmetic)の中から最良の完全な結果を選択しました。
[画像: 年ごとの最良サポートビルド]
前のグラフと似ていますが、wide_arithmetic から本当に恩恵を受けた Wasmtime と Wasmer を除きます。
最良サポートビルドでランク付けされた、現在の完全な結果は次のとおりです:
[画像: 2026年リリース、最良サポートビルド、ランク付け]
CPU機能バリアント
WebAssemblyの機能の話は、年ごとのランタイムの話よりも興味深いです。
2026年リリースでは、集計された遅延は次のとおりでした:
[画像: 2026年リリース全体でのCPU機能バリアント]
lime1 と simd128 だけでは魔法ではありません。時には役立ちますが、時には悪影響を与え、時にはその差がベンチマークのノイズに埋もれてしまいます。
wide_arithmetic は異なります。
私がテストした完全な安定リリース行の中で、wide_arithmetic ビルド全体を実行できたのは Wasmtime と Wasmer だけでした。WAMR はサポートされていないオペコード 0xfc13 でこれを拒否しました。しかし、wide_arithmetic が機能した場合、それは実験全体で最大の速度向上でした:
Wasmtime 46.0.0: それなしではネイティブの2.41倍、それありではネイティブの1.46倍。Wasmer 7.1.0: それなしではネイティブの2.08倍、それありではネイティブの1.33倍。
これは私が好む種類の変化です。libsodiumの高負荷な操作の多くは算術演算が中心です。WebAssembly ISAがその算術演算を直接表現できれば、ランタイムはCコンパイラが既に知っていたことを再発見する作業が大幅に少なくなります。
エラー
ほとんどの実行はクリーンに完了しましたが、すべてではありませんでした。
Bun 1.2.17 はベースラインビルドで box_easy を失敗しました。Bun 1.1.16 は lime1 および lime1+simd128 ビルドで pwhash_argon2i を失敗しました。
Node 22.3.0 は当初、ベースライン、lime1、およびlime1+simd128 ビルドで pwhash_argon2i、pwhash_argon2id、およびpwhash_scrypt を失敗しました。NodeのJavaScriptヒープまたはスタック設定を増やしても、これらの失敗は修正されませんでした。Wasmモジュールに明示的な最大線形メモリを割り当てることで修正されました。ベースラインビルドで、1024ページ(64 MiB)の最大メモリを割り当てると、pwhash_argon2i、pwhash_argon2id、およびpwhash_scrypt が完了しました。しかし、pwhash_scrypt は512ページで失敗し、1536ページ以上で再びセグメンテーション違反を起こしたため、これは単純な「メモリが多いほど良い」設定というよりは、V8のメモリモードのしきい値のようです。
WAMR 2.1.0(2024年のスロット)は、AOTモードでベースラインモジュールさえコンパイルできませんでした。WAMR 2.3.1 および 2.4.4 は、ベースライン、lime1、およびlime1+simd128 ビルドをコンパイルして実行しましたが、wide_arithmetic は実行できませんでした。
これらのエラーは集計から除外されました。中央値がゼロと報告されたベンチマーク行も同様です。
では、ランタイムは高速化しているのか?
一部のランタイムはそうです。
Wasmtime は最も明確な「はい」です:このベンチマークでは、毎年少しずつ高速化しました。
Node も「はい」ですが、その傾斜は緩やかです。
Bun は2025年から2026年にかけて大きな「はい」を示しました。このワークロードにはまだ多くの改善の余地がありますが、無視できないほどの改善です。
Wazero はほぼ横ばいです。
WAMR も、ここで動作したバージョン間ではほぼ横ばいですが、ネイティブの約1.4倍から1.6倍で「横ばい」というのは非常に良い状態です。
Wasmer はベースラインのみを見ると混在していますが、wide_arithmetic をサポートする2026年リリースは、暗号コードの実用的な答えを変えます。この機能を有効にすると、比較可能な通常の最新リリースの中で最速の2026年の結果でした。
wasm2c は依然として良好です。WebAssemblyを事前にCに変換し、ホスト用にコンパイルできるなら、それに勝つのは難しいです。
WAVM は最速の2026年ベースライン数値を出しましたが、公平な2024年または2025年の比較がありません。
WasmEdge は、AOTモードに強制されれば依然として優れています。誤ってインタープリターモードで実行されたことは、コマンドラインのデフォルトもベンチマークの一部であるという良いリマインダーでした。
まとめ
CPU負荷の高い暗号処理をWebAssemblyで実行する場合、ランタイムの選択は依然として非常に重要です。
最速の完全な最新結果と最も遅い最新結果の差は大きいです:wide_arithmetic を使用した Wasmer はネイティブの1.33倍でしたが、現在の Bun のベースラインはネイティブの8.77倍でした。
機能サポートも重要です。WebAssemblyモジュールがより優れた算術命令を使用できる場合、同じランタイムが「かなり良い」から「ネイティブに驚くほど近い」へと移行できます。
安心できるのは、主要なランタイムが停滞していないことです。Wasmtime は着実に改善しました。Bun は大きな飛躍を遂げました。Wasmer は実際の暗号ワークロードにとって重要な機能を追加しました。WasmEdge はAOT実行モードが明示された後も高速でした。
あまり安心できないのは、WebAssemblyのパフォーマンスが依然として単一のものではないということです。ランタイム、リリース、有効化されたWebAssembly機能、コードがJavaScriptからWASIを経由するかどうか、そして事前にネイティブコンパイルが許可されるかどうかに依存します。
したがって、実際のワークロードをベンチマークしてください。
しかし、あなたのワークロードがlibsodiumのようなものであれば、2026年の答えは次のようになります:WebAssemblyはネイティブに近づくことができ、wide_arithmetic は気にする価値があり、そしてはい、一部のランタイムは本当に高速化しています。