性能比较
已测的数值与数组内核领先 OCaml+Flambda;动态回调仍有差距,与 C 的比较也尚未全面领先。 本页公开测量条件、原始样本及局限,不把局部基准当作整门语言的速度承诺。
发布于 2026-09-21 · 样本采集于 2026-09-20 · 语言源码版本 f7fcbe86。
与 OCaml+Flambda 比较
单位为毫秒,越小越好。豫言启用实验选项 --wasm-stack,该选项目前默认关闭。 对照为 OCaml 原生机器码,不是 OCaml/Wasm。
| 程序 | 规模 / 回调 | 豫言 Wasm | OCaml+Flambda |
|---|---|---|---|
| 斐波那契 | 38 | 40.182 | 91.999 |
| 斐波那契 | 40 | 105.123 | 247.624 |
| 素数筛 | 2,000,000 | 3.154 | 4.735 |
| 素数筛 | 10,000,000 | 16.379 | 24.755 |
| 矩阵乘法 | 300 | 18.667 | 26.915 |
| 矩阵乘法 | 600 | 155.887 | 223.139 |
| 快速排序 | 1,000,000 | 8.325 | 112.810 |
| 快速排序 | 4,000,000 | 35.462 | 488.818 |
| 数组基准 | 2,000,000 | 0.535 | 2.746 |
| 数组基准 | 10,000,000 | 2.619 | 14.223 |
| 高阶调用 | 4,000,000 / 加一 | 5.149 | 4.223 |
| 高阶调用 | 4,000,000 / 乘三 | 5.698 | 4.769 |
树构造与求和另测深度 18、20:豫言分别为 0.003、0.001 ms,OCaml 为 4.297、25.388 ms。豫言已消除这两个程序的实际树构造,结果接近计时分辨率;不将它解释成通用树分配或 GC 吞吐量的速度倍数。
与 C/Wasm 比较
这是独立测量批次,不能把本表的耗时与上表直接横比。C 使用 WASI SDK clang 23.1.0、-O3;双方均在同机 Node Worker 中运行。下面仅展示原版产物,未采用省检原型。
| 快速排序规模 | 豫言 Wasm | C/Wasm | 豫言耗时差异 |
|---|---|---|---|
| 1,000,000 | 8.157 ms | 7.847 ms | 约多 4.0% |
| 4,000,000 | 34.151 ms | 33.318 ms | 约多 2.5% |
这组排序接近 C,但尚未超过。不同运行批次仍存在波动,不能挑选最好的一轮宣布全面胜过 C。
自举墙钟时间
当前 Wasm 编译器两次完整冷编译缓存自举分别为 15.55 秒、15.87 秒;种子与两代产物逐字节一致。使用 Node、18 个并行任务及 --do-not-load-cache,未清除操作系统页缓存。这是整次编译的墙钟时间,与上面的算法内核计时不同。
原生验证链三步分别为 58.044、81.926、79.054 秒,第三、四代产物相同。不能把 Wasm 的数字写成“所有后端自举均低于 30 秒”,也没有同等 OCaml 自举测量可供比较。
测试条件与范围
- 本机:Apple M5 Pro,18 核、48 GB;Node 26.3.0 / V8 14.6.202.34-node.20,默认引擎设置。
- OCaml:5.5.0,实测编译器配置
flambda: true,ocamlopt -O3,保留安全数组访问,未用-unsafe;这是官方 Flambda,不是 Flambda 2。 - Flambda 对照:每项三个独立进程,每进程六轮;双方交错运行,首轮单列,后五轮共 15 个样本取中位数。14 项共 504 轮,结果校验和一致,测量期间没有并发构建。
- C 排序对照:每项七个独立进程,每进程六轮,热中位数来自后五轮共 35 个样本;同时交错测量的两种省检原型没有用于上表。
- 内核耗时不包含进程启动、模块加载和结果打印;按程序包含分配、填充及计算。校验和一致不等于本次对每个中间数组都逐元素验证。
- 这些程序不能代表所有应用、尾延迟、长期内存占用、I/O 或完整操作系统性能。极小数组频繁创建时,当前栈路径仍可能慢于 GC,因此暂不默认启用。
原始数据与复现
下载测量样本与产物哈希(JSON)。数据保留首轮、各进程各轮值;页面只展示中位数,不以单次最优值作比较。
从上述源码版本构建豫言内核时使用 --target=wasmgc --wasm-stack,由 工具/节点网页汇编宿主/宿主.cjs 运行;OCaml 对照使用启用了 Flambda 的 ocamlopt -O3,并链接同目录 单调钟.c。源码中的每次调用自行输出六轮计时。固定输入和运行时版本,交错运行多个新进程后再比较。