Web開発
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ベンチマークのフォローアップです。「最新バージョンが1つのマイクロベンチマークでネイティブコードを上回るか?」でもなく、「どのランタイムが最も見栄えの良いベンチマークチャートを持っているか?」でもなく、もっと退屈で有用なこと:同じ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、ZigでローカルCPUターゲットでコンパイル
プレーンWebAssembly
WebAssembly (lime1付き)
WebAssembly (lime1とsimd128付き)
WebAssembly (lime1, simd128, および wide_arithmetic 付き)
ネイティブ参照として、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コンパイラは無効なWASMスタックデータ型でこれらのZig生成モジュールで失敗しました。マトリックスにはバージョンを含めましたが、集計には含めませんでした。
ベースラインWebAssembly
これは、lime1、SIMD、またはワイド算術を使用しない、プレーンなWebAssemblyビルドです。普遍的なトレンドはありません。Wasmtimeは着実に改善しました:2024年はネイティブの2.67倍、2025年は2.54倍、2026年は2.41倍でした。毎年速くなり、ノイズの上に、0.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年にわずかに改善しました。Ahead-of-time(AOT)ネイティブ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を除きます。最良サポートビルドでランク付けすると、現在の完全な年次結果は次のようになります:
CPU機能バリアント
WebAssemblyの機能ストーリーは、年ごとのランタイムストーリーよりも興味深いです。2026年リリースでは、これらの集計遅延がありました:lime1とsimd128だけでは魔法ではありません。時には役立ち、時には害になり、時には差がベンチマークノイズに埋もれます。wide_arithmeticは異なります。私がテストした完全な安定リリースの中で、WasmtimeとWasmerだけが完全なwide_arithmeticビルドを実行できました。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は最もクリーンな