编程与软件工程mrale.ph
也许你不需要 Rust 和 WASM 来加速 JS
Maybe you don't need Rust and WASM to speed up your JS
2018 — 2021,它一次次回到首页
黑点是上首页(≥ 50 分)的那次投稿,空心点是没冲上去的投稿,点越大分数越高。
导读
这是 V8 工程师 Vyacheslav Egorov(mrale.ph)的长文:针对“某个 JS 库被 Rust+WASM 重写后快了好几倍”的案例,他亲手对原有的纯 JS 实现做剖析和逐项优化,展示通过调整数据结构、减少内存分配、写出对 JIT 友好的代码,JS 也能把大部分性能追回来;文中还用简单的估算来指导该往哪儿优化。
为什么经久不衰:它既是“先测量、再优化”的实战示范,也把一个至今仍在争论的问题摆上台面:依赖引擎内部细节换来的性能,是否值得长期维护。
HN 评论精选
文章读下来反而支持 WASM:手工 JS 优化的门槛高、可预测性差。
这篇对性能剖析和改进过程的描述很有意思,但我读完的感受恰恰和标题相反。JS 优化能带来这么多收益确实很酷,可文章里这些手段显得相当不确定;如果开发者不熟悉 VM 内部,我不认为大多数人能走完这条路。用 wasm+rust/c++ 的部分吸引力就在于开箱即能得到可预测得多的性能。当性能来自语言特性而非某个 VM 的特定优化时,跨版本维护更容易,也更不容易因引擎变动而回退。
anp查看英文原文
I think this is an interesting exploration because I really enjoyed the description of profiling and improving performance, but I came away feeling exactly the opposite of the title. I think it's really cool that JS optimization can provide so many wins, but this article makes it seem fairly fickle and if they're not familiar with VM internals I would not expect most developers to complete this journey. Using wasm+rust/c++ is interesting in part because you can get so much more predictable performance out of the box. When the performance comes from language features instead of VM-specific optimizations the performance might be easier to maintain across revisions and hopefully will be less subject to regression from VM changes.
提醒:大 O 分析在小 N 场景下会被常数因子主导,别盲信。
对文中“快排一个 10 万元素数组,还是快排 3333 个 30 元素子数组”那段数学估算要小心。大 O 说的是 N 很大时的行为,所以习惯上省略小因子;但每一项其实都有隐含的常数系数,在 N 小时系数可能更关键。我见过 O(N^2+N) 的代码,小 N 时反而是那个 N 项更重要;盲目去优化“更大”的那一项,可能白费功夫。
eslaught查看英文原文
> Is it better to quick-sort one array with 100K elements or quick-sort 3333 30-element subarrays? > A bit of mathematics can guide us (100000log100000 is 3 times larger than 3333×30log30) You have to be careful doing this kind of analysis. Big-O is explicitly about what happens for large values of N. It is traditional to leave off smaller factors, because they don't matter at the limit of N going to infinity. There is implicitly a constant coefficient on each component, and that might matter more at small N. So e.g. I've seen cases that were O(N^2 + N), and which of course you'd traditionally write as O(N^2), but where the O(N) factor mattered more at small values of N because of constant factors. Depending on whether you cared more about small or large values of N, would guide whether you'd actually want to go after the O(N^2) factor or not. If you just blindly went for the larger factor, you could waste a lot of time and not actually accomplish anything.
后续讨论中双方都改进了实现,但结论仍是要可预测性能就得用 WASM。
后来围绕这个优化有过一轮往返讨论(见 Steve 找到的链接)。WASM 版本也吸收了这里提出的算法改进而变得更快,而 Rust 作者的结论是:想要可预测的性能,你确实需要 WASM。高性能 JS 依赖于始终不偏离 JIT 的“快路径”、不惹恼 GC,这些是不成文的技巧,很难在所有 JS 引擎上做到;今天优化得很好的 JS,明天换个新 JIT 实现就可能撞上性能悬崖,从来没有保证。
pornel查看英文原文
There was a back-and-forth on optimizing this (see the link Steve found). The WASM version got faster too by adopting algorithmic changes proposed here, and the conclusion of Rust authors was that you do need WASM if you want predictable performance. High-perf JS relies on staying on the JIT happy path, not upsetting GC, and all of this is informal trickery that's not easy to do for all JS engines. There's never any guarantee that JS that optimizes perfectly today won't hit a performance cliff in a new JIT implementation tomorrow.
多数场景 WASM 优势有限,但在规避 GC 压力和内存分配上明显更强。
JS 的 JIT 已经非常好了,改用 WASM 大概率不会带来大的性能提升。不过 WASM 有一个 JS JIT 很难竞争的优势:GC 压力。只要你的 WASM 库尽量用栈上分配,同等功能的 JS 原生算法就很难与之竞争,尤其是在涉及大量对象/状态管理时。但对于做浮点计算的热点数学循环(比如曼德博集合),我见过 JS 和 WASM 性能完全一样,挺不可思议的。
cogman10查看英文原文
Javascript JITs are really good, you (likely) aren't going to see major performance improvements by dropping into WASM. That said, one major benefit of WASM that Javascript jits will have a hard time competing with is GC pressure. So long as your WASM lib focuses on stack allocations, it'll be real tough for a Javascript native algorithm doing the same thing to compete (particularly if there's a bunch of object/state management). For a hot math loop doing floating point calcs (mandelbrot calc), however, I've seen javascript end up with identical performance compared to WASM. It's really pretty nuts.
历次讨论
同类还值得读
开源应用架构
The Architecture of Open Source Applications
《开源软件架构》(AOSA)是一本在线免费书,邀请知名开源项目的作者亲自剖析其内部设计,涵盖 SQLAlchemy、LLVM、Audacity、Apache、Bash 等系统。
编程与软件工程上首页 9 次 · 2011–2024aosabook.org编辑精选编程语言简史:简短、不完整且多半错误
A Brief, Incomplete, and Mostly Wrong History of Programming Languages
一篇以戏谑、故意不准确的方式回顾编程语言史的博客文章,用夸张轶事和讽刺定义串起 Lisp、C、C++、Java、JavaScript、PHP 等语言。
编程与软件工程上首页 8 次 · 2009–2021james-iry.blogspot.comSQLite 是如何测试的
How SQLite is tested
SQLite 官方文档页,系统介绍 SQLite 的测试体系:多种测试方法(TCL 测试、模糊测试、回归测试、静态分析等)和海量测试用例,展示了这个小型开源项目如何靠极致测试获得…
编程与软件工程上首页 8 次 · 2009–2025sqlite.org编辑精选高级编程语言(2009)
Advanced programming languages (2009)
Matt Might 的经典文章,按用途推荐“高级编程语言”:如果追求就业就选主流语言,如果追求表达力、学术研究或创业,则推荐 Haskell、OCaml、Scala 等函数式语…
编程与软件工程上首页 8 次 · 2009–2022matt.might.net我的 Forth 与栈机器经历
Yosefk - My history with Forth & stack machines
作者以亲身经历回顾了使用 Forth 语言和栈式机器的历程:既赞叹其简洁优雅、代码量小、可自举的优点,也坦率指出栈操作在实际编程中的痛苦,以及 Forth 社区文化中的问题。
编程与软件工程上首页 8 次 · 2010–2024yosefk.com编辑精选