WebAssembly 值得用的场合,比宣传里少得多

WASM 的收益来自「计算密集 + 大批量数据 + 少的跨界调用」。把一个 O(n) 的 JS 循环改写成 WASM,通常只会得到更慢的加载和更难调的栈。

WebAssembly 的宣传语是「接近原生的速度」。这句话本身没错,但它描述的是算完之后的状态,把装载、编译、跨界调用和数据拷贝都省略了。

收益来自三个条件同时成立

  1. 计算密集:单次调用里有真实的计算量,不是几次加减乘除
  2. 批量数据:一次喂进去一大块,而不是来回传小数组
  3. 调用少:跨边界的次数比计算本身少一个数量级

三条同时成立时,WASM 能快到十倍以上。少任何一条,收益就被边界成本吃掉。

真正值得用的一类

已经有一份 C / C++ / Rust 的实现,且它在热点路径上:图片与音视频编解码、压缩(zstd、brotli 的高压缩档)、密码学、物理与几何计算,以及需要确定性沙箱的场景(用户提交的表达式求值、插件系统)。这些的共同点是:算法本身复杂、边界清晰、数据是块状的。

不适合的三类

  • 操作 DOM:WASM 碰不到 DOM,所有操作要经 JS 转发,一次跨界的成本可能比操作本身还高
  • 小字符串处理:正则、模板、格式化 —— 输入输出小,边界成本占主导
  • 单纯为了「性能」重写一遍 JS:JIT 对整数循环、对象属性访问已经足够好,重写往往换不来收益,却换来一条更难调的栈

本站的选择:一个都不用

这个站点上最重的计算是数独求解、生命游戏迭代、哈希与图像处理,全是毫秒级。加一个 WASM 模块意味着多几 MB 的下载、一次编译、一条只能在浏览器控制台里调的调用链 —— 换来的是感知不到的加速。

先量。如果瓶颈是一个 O(n) 循环,换个语言写它并不会变成 O(log n)。

← 返回文章列表

评论

…