
2026/09/09 19:00
2026年のWebAssemblyランタイムの性能
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
日本語翻訳:
元の要約は明確で簡潔であり、源データを忠実に反映しています。あいまいな表現や混乱を招く言語を用いることなく、主なメッセージを効果的に伝えています。
Text to translate
The original summary is clear, concise, and faithful to the source data. It effectively conveys the main message without introducing vague phrasing or confusing language.
本文
WebAssembly ランタイムの性能検証とベストプラクティス
以前(2019 年・2021 年・2023 年)実施された libsodium の WebAssembly ベンチマークに続き、**「最新のランタイムがネイティブコードを凌駕するか」あるいは「どのランタイムが最も高速か」**を確認しました。
マイクロベンチマークの議論ではなく、実用的な問いです:同じ C 言語による暗号コードを最新、1 年前、2 年前の WebAssembly ランタイムで実行し、実際の性能改善が見られるのか。
結論(短縮版)
- Wasmer が最もパフォーマンスが高く、その次は WAVM、WAMR、Wasmtime で差が小さいです。
- WAVM は最適化機能が優れており、標準的な Portable WebAssembly から非常に高速なコードを生成できます。
- ランタイムがサポートする際、暗号コードに対しては WebAssembly の汎用算術命令(
)の導入が大きな意味を持ちます。wide_arithmetic
測定環境と内容
テストプログラム
libsodium コミット
8e3be8615ba6adcd7babaecf5e76f516890ba5fb からビルドされたベンチマークスイートを使用。
構築バリアント
ネイティブの基準線として 1 つと、以下の WebAssembly バリアントを構築しました。
| バリアント | 説明 |
|---|---|
| ネイティブ x86-64 | Zig を使用し、ローカル CPU ターゲット指定 () |
| 標準的な WebAssembly | Lime1 なし、SIMD なし |
| Lime1 | 機能付与 |
| Lime1 + SIMD128 | と を追加 |
| Lime1 + SIMD128 + Wide Arithmetic | さらに汎用算術 () を追加 |
コンパイル設定
- ネイティブ基準値:
オプションを使用。-Dcpu=native - WAVM (wasm2c):
でコンパイル。zig cc -O3 -march=native - WAMR (AOT モード):
非対応のため、ホスト利用可能機能 (--cpu=native
) と整合する設定を使用。x86_64-v4--target=x86_64 --cpu=x86-64-v4 --opt-level=3
実行環境
- CPU: AMD Ryzen AI 9 HX 470(12 コア・24 スレッド)
- CPU ブースト無効化、最大クロック周波数設定
2 GHz
- CPU ブースト無効化、最大クロック周波数設定
- OS: Linux 7.1.0-rc7
- Zig: 0.17.0-dev.948+e949341b7
データ集計方法
各ベンチマークのスローダウン率(ネイティブに対する比率)の幾何平均です。
- 値が低いほど良い(例:
は「ネイティブの 2 倍遅い」を意味)。2.0
を使用したため、小さいテストはノイズが大きく量子化されています。ITERATIONS=3- 集計には、ゼロ時間を報告した行は除外しました。
ランタイムのバージョン比較
| ランタイム | 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 の歴史的比較は困難です(古いバイナリが実行拒絶)。WAMR 2.1.0 は AOT コンパイルで失敗したため集計から除外。
ベース WebAssembly ビルドの傾向分析
普遍的な傾向はありませんでしたが、特定のランタイムでは明確な改善が見られました。
- Wasmtime: 年々安定して高速化しました(2024 年:2.67 倍 → 2025 年:2.54 倍 → 2026 年:2.41 倍)。
- Node: 緩やかに改善し、スローダウン率が減少しました(8.60 倍 → 7.95 倍)。
- Wazero: ほぼ横ばいです(4.84 倍 → 4.72 倍)。実質的な変化はありません。
- WAMR (AOT): 2025 年から高速化し、2026 年でも同等維持(1.59 倍 → 1.57 倍)。
- Wasmer: 2025 年版で退歩しましたが、2026 年版で回復。2024 年とほぼ遜色ない性能を維持。
- wasm2c: 2026 年で適度な改善が見られ、AOT 変換可能なため依然として最良の選択肢の一つです。
- Bun: 2024/25 年は劣っていましたが、2026 年に劇的な改善(約 3 倍)を遂げました。
- WasmEdge: コマンドライン振る舞いの修正により正常化。AOT モード設定で 1.74 倍になり、中間位置に復帰。
CPU 機能バリアントによる性能向上
WebAssembly の機能導入による影響はランタイムごとに異なります。
Lime1 / SIMD128
- ここでの魔法ではありません。状況によって助けになる場合もあれば、害になる場合もあり、ノイズに埋もれることもあります。
汎用算術 (wide_arithmetic) ⭐ 最重要
- 実験全体で見られる最大の速度向上をもたらしました。
- Wasmtime と Wasmer のみがフルな汎用算術ビルドを実行可能でした。
比較データ(ネイティブに対するスローダウン率)
| ランタイム | 汎用算術なし | 汎用算術あり (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: 初期設定では
,pwhash_argon2i
,argon2id
で失敗。scrypt- JavaScript ヒープ/スタック増設では修正不可能でした。
- 解決策: Wasm モジュールに明示的な最大線形メモリを指定 (
) することで修正可能になりました。1024 ページ / 64 MiB - ※ただし、これは V8 のメモリアドレスモードの閾値であり、「単純にメモリを増やす」という意味ではありません(512 ページでは失敗、1536 ページ以上でセグメンテーション)。
- WAMR 2.1.0: AOT モードでも基準モジュールがコンパイルできませんでした。
- WAMR 2.3.1 / 2.4.4: 汎用算術ビルドはサポートされていませんでした。
注意: 上記の失敗した行と、中央値がゼロだったベンチマーク行は集計から除外しました。
ランタイムは本当に高速化しているか?
結論:はい、いくつかのランタイムは明確に高速化しています。
| ランタイム | 評価 |
|---|---|
| Wasmtime | ✅ 明確な「はい」:毎年少しずつ高速化。 |
| Node | ⚠️ 「はい」だが緩やか: 改善傾向はありますが傾斜が緩い。 |
| Bun | 🚀 劇的な「はい」: 2025→2026 で大きな飛躍。改善の余地はまだある。 |
| Wazero | ➖ ほぼ横ばい: 実質的な変化なし。 |
| WAMR | ⭐ 優れた位置: 「横ばい」だが、ネイティブ比 1.4〜1.6 倍という極めて優秀な領域にある。 |
| Wasmer | ✅ 回復・最適化: 汎用算術サポートにより、実用的な答えに達した。 |
| wasm2c | ⭐ 最良: ネイティブ C への AOT 変換可能なため、超えにくい。 |
| WAVM | ✅ 最高値: 2026 ベースでは最も高速だが、過去データ不足。 |
| WasmEdge | ✅ 修正により安定: AOT モード設定で高速化維持。 |
まとめと推奨事項
WebAssembly で CPU 負荷の高い暗号を実行する場合でも、ランタイムの選択は依然として非常に重要です。
1. 性能の差が大きい
- Wasmer (汎用算術あり): ネイティブ比
倍1.33 - Bun (基準値): ネイティブ比
倍8.77- 同じ環境でも約 6 倍の差が出る可能性があります。
2. 機能サポートが重要
同じランタイムでも、汎用算術指令 (
) を利用できるようになることで、「まあまあ良い」から「驚くほどネイティブに近い」へと変化します。wide_arithmetic
3. 主流のランタイムは停滞していない
- Wasmtime: 安定して改善し続けています。
- Bun: 大きな飛躍を果たしています。
- Wasmer: 暗号ワークロードにとって重要な機能(汎用算術)を獲得しました。
- WasmEdge: AOT ラン実行モードの明示化により、高速化を維持しています。
アドバイス
WebAssembly のパフォーマンスはランタイム、リリース、有効な機能、JS→WASI のパス、AOT コンパイルの有無などによって依存します。実際のワークロードをベンチマークしてください。
しかし、あなたのワークロードが libsodium に見られる場合、2026 年の答えは以下の通りです:
- WebAssembly はネイティブに近いことが可能。
- 汎用算術 (
) は必須。wide_arithmetic - はい、一部のランタイム(Wasmer, Wasmtime など)は本当に高速化しています。