2026 年 WebAssembly 运行时性能
摘要
本文使用 libsodium 加密库对多种 WebAssembly 运行时(WAVM、WasmEdge、WAMR、wasm2c、Wasmer、Wasmtime、Wazero、Node、Bun)进行了性能基准测试,比较了 2024、2025 和 2026 年的版本。结果显示,WAVM、WasmEdge(AOT)、WAMR(AOT)、wasm2c、Wasmer 和 Wasmtime 在 CPU 密集型加密任务中实现了接近原生的性能,而 wide_arithmetic 指令对加密代码有益。
<p><a href="https://lobste.rs/s/fhmvsf/performance_webassembly_runtimes_2026">评论</a></p>
查看缓存全文
缓存时间:
2026/06/23 17:48
# 2026年WebAssembly运行时性能
来源:https://00f.net/2026/06/23/webassembly-runtimes-2026/
我想知道 WebAssembly 运行时是否在变得更快。
这是对之前 libsodium WebAssembly 基准测试的跟进:2019,2021,2023。
不是“新版本是否在某个微基准测试中击败了原生代码?”,也不是“哪个运行时的基准测试图表最漂亮?”,而是更无聊但更有用的东西:
如果我采用相同的 C 加密代码,将其编译为 WebAssembly,并在最新运行时、一年前运行时、两年前运行时上运行,性能是否真的有提升?
因此,我对 libsodium 在 2024 年 6 月、2025 年 6 月和 2026 年 6 月左右发布的 WebAssembly 运行时上进行了基准测试。
简要版本:
- `WAVM` 和 `WasmEdge` 可以非常快。`WasmEdge 0.17.0` 需要显式指定 `--run-mode=aot`;否则编译后的模块像解释器模式的 Wasm 一样运行。
- `WAMR` 的 AOT 模式也非常快,与 `WAVM` 和最好的 `Wasmtime` 结果并列。
- `wasm2c`、`Wasmer` 和 `Wasmtime` 都足够接近原生,对于 CPU 密集型加密任务很有吸引力。
- `Wazero` 较慢,但稳定。
- `Node` 和 `Bun` 行需要重新运行更长的基准循环。一次快速测试表明,短循环运行未能充分预热 JIT。
- 实验性的 WebAssembly `wide_arithmetic` 指令对于支持它们的运行时的加密代码来说意义重大。
## 我测量了什么
测试程序是 libsodium 的基准测试套件,基于 libsodium 提交 `8e3be8615ba6adcd7babaecf5e76f516890ba5fb` 构建。
我构建了一个原生基线和几个 WebAssembly 变体:
- 原生 x86-64,使用 Zig 并以本地 CPU 为目标编译
- 普通 WebAssembly
- 带 `lime1` 的 WebAssembly
- 带 `lime1` 和 `simd128` 的 WebAssembly
- 带 `lime1`、`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
``
主机是 AMD Ryzen AI 9 HX 470,12 核 24 线程。CPU 睿频已禁用,最大 CPU 频率为 2 GHz。操作系统是 Linux 7.1.0-rc7,Zig 版本为 `0.17.0-dev.948+e949341b7`。
下面的数字是每个基准测试相对于原生构建的几何平均减速比。越低越好。值为 `2.0` 表示“在此机器上比原生慢两倍”。
我使用了 `ITERATIONS=3`,因此非常小的 libsodium 测试会有噪声和量化效应。报告时间为零的行已从聚合中排除。我没有将基准测试进程绑定到特定核心。这对于比较运行时的大致行为仍然有用,但不要将最后一位小数视为有意义的。
## 版本
对于除 `WAVM` 之外的所有运行时,我使用了 2026 年 6 月 23 日可用的最新稳定版本,以及大约一年前和两年前的稳定版本。
| Runtime | 2024 | 2025 | 2026 |
|---------|------|------|------|
| `Bun` | `1.1.16` (https://github.com/oven-sh/bun/releases/tag/bun-v1.1.16) | `1.2.17` (https://github.com/oven-sh/bun/releases/tag/bun-v1.2.17) | `1.3.14` (https://github.com/oven-sh/bun/releases/tag/bun-v1.3.14) |
| `Node` | `22.3.0` (https://nodejs.org/dist/v22.3.0/) | `24.2.0` (https://nodejs.org/dist/v24.2.0/) | `26.3.1` (https://nodejs.org/dist/v26.3.1/) |
| `WAMR` | `2.1.0` (https://github.com/bytecodealliance/wasm-micro-runtime/releases/tag/WAMR-2.1.0) | `2.3.1` (https://github.com/bytecodealliance/wasm-micro-runtime/releases/tag/WAMR-2.3.1) | `2.4.4` (https://github.com/bytecodealliance/wasm-micro-runtime/releases/tag/WAMR-2.4.4) |
| `WABT wasm2c` | `1.0.35` (https://github.com/WebAssembly/wabt/releases/tag/1.0.35) | `1.0.37` (https://github.com/WebAssembly/wabt/releases/tag/1.0.37) | `1.0.41` (https://github.com/WebAssembly/wabt/releases/tag/1.0.41) |
| `WasmEdge` | `0.14.0` (https://github.com/WasmEdge/WasmEdge/releases/tag/0.14.0) | `0.14.1` (https://github.com/WasmEdge/WasmEdge/releases/tag/0.14.1) | `0.17.0` (https://github.com/WasmEdge/WasmEdge/releases/tag/0.17.0) |
| `Wasmer` | `4.3.2` (https://github.com/wasmerio/wasmer/releases/tag/v4.3.2) | `6.0.1` (https://github.com/wasmerio/wasmer/releases/tag/v6.0.1) | `7.1.0` (https://github.com/wasmerio/wasmer/releases/tag/v7.1.0) |
| `Wasmtime` | `22.0.0` (https://github.com/bytecodealliance/wasmtime/releases/tag/v22.0.0) | `34.0.0` (https://github.com/bytecodealliance/wasmtime/releases/tag/v34.0.0) | `46.0.0` (https://github.com/bytecodealliance/wasmtime/releases/tag/v46.0.0) |
| `WAVM` | n/a | n/a | `nightly/2026-04-05` (https://github.com/WAVM/WAVM/releases/tag/nightly/2026-04-05) |
| `Wazero` | `1.7.3` (https://github.com/wazero/wazero/releases/tag/v1.7.3) | `1.9.0` (https://github.com/wazero/wazero/releases/tag/v1.9.0) | `1.12.0` (https://github.com/wazero/wazero/releases/tag/v1.12.0) |
`WAVM` 在历史比较上有些棘手。旧的可用 nightly 版本对于 2024 和 2025 两个时间段都退化为 2022 年的二进制文件,并且该二进制文件拒绝在此机器上运行。我只保留了 2026 年的 nightly 版本。
`WAMR 2.1.0`(选定的 2024 版本)安装正常,但其 AOT 编译器在这些 Zig 生成的模块上失败,报 `invalid WASM stack data type`。我在矩阵中保留了该版本,但未包含其聚合结果。
## 基准 WebAssembly
这是普通的 WebAssembly 构建,没有 `lime1`、SIMD 或 wide arithmetic。
| Runtime | 2024 | 2025 | 2026 |
|---------|------|------|------|
| `WAVM` | n/a | n/a | 1.41 |
| `WAMR AOT` | n/a | 1.59 | 1.57 |
| `WasmEdge` | 1.66 | 1.98 | 1.74 |
| `wasm2c` | 2.01 | 2.08 | 1.86 |
| `Wasmer` | 2.13 | 2.56 | 2.08 |
| `Wasmtime` | 2.67 | 2.54 | 2.41 |
| `Wazero` | 4.84 | 4.70 | 4.72 |
| `Node` | 8.60 | 8.22 | 7.95 |
| `Bun` | 27.41 | 26.42 | 8.77 |
没有一个普遍的趋势。
`Wasmtime` 稳步提升:2024 年 2.67 倍原生,2025 年 2.54 倍,2026 年 2.41 倍。这不是革命性的,但确实是实实在在的进步。
`Node` 也缓慢提升,从 8.60 倍原生到 7.95 倍原生。
`Wazero` 基本持平:4.84 倍, 4.70 倍, 4.72 倍。这不算差,但该基准测试未显示出过去两年的大幅加速。
`WAMR` 的 AOT 模式在 2025 年已经很快,2026 年稍快:1.59 倍原生,然后是 1.57 倍原生。我没有完整的 2024 年 WAMR 数据,因为 `WAMR 2.1.0` 无法编译这些模块。
`Wasmer` 在我测试的 2025 版本中出现了性能退步,然后在 2026 年恢复。2026 年的基准比 2024 年稍快,但幅度不大。
`wasm2c` 在 2026 年有适度提升。如果提前将 WebAssembly 翻译为原生 C 适合你的部署模型,它仍然是最佳选择之一。
`Bun` 是异常值。其 2024 和 2025 年的结果远落后,但 2026 年的结果比 2025 年快约三倍。在此基准测试中仍比 `Node` 慢,但方向极好。
`WasmEdge` 也很快,但其命令行行为变化足够大。我第一次 `0.17.0` 运行时不小心对编译后的模块使用了解释器模式,结果看起来异常慢。使用 `--run-mode=aot` 运行编译后的模块后问题解决:2026 年基准为 1.74 倍原生,介于 2024 年和 2025 年基准结果之间。
## 按年份的最佳支持构建
基线表格很有用,因为它处处比较相同的 WebAssembly 目标。
但如果你为自己的部署选择运行时,你可能更关心该运行时实际能运行的最快构建。
因此,对于每个运行时和年份,我还从支持的构建中选择了最佳完整结果:基线、`lime1`、`lime1+simd128` 和 `lime1+simd128+wide_arithmetic`。
| Runtime | 2024 best | 2025 best | 2026 best |
|---------|-----------|-----------|-----------|
| `WAVM` | n/a | n/a | 1.41 (baseline) |
| `WAMR AOT` | n/a | 1.42 (`lime1+simd128`) | 1.42 (`lime1+simd128`) |
| `WasmEdge` | 1.62 (`lime1+simd128`) | 1.64 (`lime1`) | 1.64 (`lime1`) |
| `wasm2c` | 2.01 (baseline) | 2.08 (baseline) | 1.86 (baseline) |
| `Wasmer` | 2.09 (`lime1`) | 2.49 (`lime1`) | 1.33 (`lime1+simd128+wide_arithmetic`) |
| `Wasmtime` | 2.60 (`lime1+simd128`) | 1.52 (`lime1+simd128+wide_arithmetic`) | 1.46 (`lime1+simd128+wide_arithmetic`) |
| `Wazero` | 4.84 (baseline) | 4.64 (`lime1`) | 4.71 (`lime1+simd128`) |
| `Node` | 8.60 (baseline) | 7.99 (`lime1`) | 7.95 (baseline) |
| `Bun` | 27.35 (`lime1`) | 26.23 (`lime1`) | 8.77 (baseline) |
按最佳支持构建排序,完整的当前年份结果如下:
| 2026 排名 | Runtime | 最佳构建 | 相对原生减速 |
|-----------|---------|----------|--------------|
| 1 | `Wasmer` | `lime1+simd128+wide_arithmetic` | 1.33 |
| 2 | `WAVM` | baseline | 1.41 |
| 3 | `WAMR AOT` | `lime1+simd128` | 1.42 |
| 4 | `Wasmtime` | `lime1+simd128+wide_arithmetic` | 1.46 |
| 5 | `WasmEdge` | `lime1` | 1.64 |
| 6 | `wasm2c` | baseline | 1.86 |
| 7 | `Wazero` | `lime1+simd128` | 4.71 |
| 8 | `Node` | baseline | 7.95 |
| 9 | `Bun` | baseline | 8.77 |
## CPU 功能变体
WebAssembly 功能的故事比年度运行时故事更有趣。
对于 2026 年的版本,这些是聚合减速:
| Runtime | baseline | `lime1` | `lime1+simd128` | `lime1+simd128+wide_arithmetic` |
|---------|----------|---------|-----------------|---------------------------------|
| `WAVM` | 1.41 | 1.59 | 1.43 | unsupported |
| `WAMR AOT` | 1.57 | 1.44 | 1.42 | unsupported |
| `WasmEdge` | 1.74 | 1.64 | 1.76 | unsupported |
| `Wasmer` | 2.08 | 2.02 | 2.03 | 1.33 |
| `Wasmtime` | 2.41 | 2.30 | 2.37 | 1.46 |
| `Wazero` | 4.72 | 4.77 | 4.71 | unsupported |
| `Node` | 7.95 | 8.05 | 8.25 | unsupported |
| `Bun` | 8.77 | 11.05 | 9.53 | unsupported |
单独的 `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 22.3.0` 的密码哈希失败无法通过增加 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` 如果只看基线则表现不一,但 2026 年版本支持 `wide_arithmetic` 改变了加密代码的实际答案。启用该特性后,它是我能够比较的正常当前版本中最快的完整 2026 年结果。
`wasm2c` 仍然很好。如果能够提前将 WebAssembly 翻译为 C 并为主机编译,它很难被击败。
`WAVM` 产生了最快的 2026 年基线数字,但我没有公平的 2024 或 2025 年比较。
`WasmEdge` 一旦强制进入 AOT 模式,仍然表现出色。意外的解释器模式运行是一个很好的提醒:命令行默认值也是基准测试的一部分。
## 要点
如果你在 WebAssembly 中运行 CPU 密集型加密任务,运行时的选择仍然非常重要。
最快的完整当前结果和最慢的当前结果之间的差距很大:`Wasmer` 搭配 `wide_arithmetic` 为 1.33 倍原生,而当前 `Bun` 基线为 8.77 倍原生。
功能支持也很重要。当 WebAssembly 模块可以使用更好的算术指令时,同一个运行时可以从“还不错”变为“惊人地接近原生”。
令人欣慰的是主流运行时并未停滞不前。`Wasmtime` 稳步提升。`Bun` 实现了巨大飞跃。`Wasmer` 获得了对真实加密工作负载很重要的特性。`WasmEdge` 在显式使用 AOT 模式后仍然很快。
不太令人欣慰的是 WebAssembly 性能仍然不是一个单一概念。它取决于运行时、版本、启用的 WebAssembly 特性、代码是否通过 JavaScript 的 WASI 运行,以及是否允许提前原生编译。
因此,请对你实际的工作负载进行基准测试。
但如果你的工作负载类似于 libsodium,2026 年的答案是:WebAssembly 可以接近原生,`wide_arithmetic` 值得关注,并且是的,一些运行时确实在变快。
相似文章
Lobsters Hottest
本文使用支持宽算术的wasm2c对WebAssembly-to-C方法进行了基准测试,证明其在速度和内存使用方面仍然与专门的WebAssembly运行时(如Wasmer和Wasmtime)具有竞争力。
OpenAI Blog
Wasmer 利用 OpenAI 的 Codex 构建了 Edge.js,这是一个运行在 WebAssembly 沙箱中的边缘计算 Node.js 运行时,将开发周期从一年缩短至两周。
Lobsters Hottest
本文介绍了WATaBoy,一个Game Boy模拟器,它使用即时编译到WebAssembly的方式,实现了超越原生解释器的性能,是JIT到Wasm在模拟领域的一个概念验证。
Hacker News Top
对新的SPEC CPU2026基准测试套件进行了深度评估,该套件取代了SPEC CPU2017,包含52个工作负载和一个更慢的参考系统(Ampere eMAG 8180),展示了现代CPU之间的性能对比。
Lobsters Hottest
SpaceWASM 是一个来自 NASA/JPL 的开源 WebAssembly 解释器,专为航天器机载序列化设计,注重确定性内存使用和在资源受限环境下的流式处理能力。