JavaScript 引擎 V8 发布了 7.4 版本, 目前处于 beta 阶段, 正式版将于几个星期后与 Chrome 74 Stable 一起发布.
此版本带来了一些新特性, 并极大提升了性能.
JIT-Less V8
V8 现在不需要运行时分配可执行内存就可以执行 JavaScript, 关于这个新特性的具体细节, 之前我们有报导过: V8 新机制: JIT-Less 模式.
webAssembly Threads/Atomics
在非 Android 操作系统上启用了 WebAssembly Threads/Atomics, 可以通过 chrom://flags/#enable-webassembly-threads 在 Chrome 中启用此功能.
此特性可以通过 WebAssembly 解锁用户计算机上多核的使用, 从而在 Web 上实现新的, 计算量大的用例.
性能提升
参数不匹配的调用速度更快
JavaScript 中允许调用函数时参数的数量与定义时不同的情况, 不管是参数少了还是多了都完全有效, 同时 JavaScript 函数可以通过参数对象, REST 参数等方式获取实际参数. 因此, JavaScript 引擎中必须提供一种获取实际参数的方法, 在 V8 中, 这是通过一种称为参数自适应的技术完成的.
参数自适应可以获取实际参数, 但却是以性能为代价的, 而这种性能损耗在现代前端和中间件框架中通常是没法避免的, 因为有太多 API 具有可选参数或可变参数列表了.
V8 7.4 版本中带来了一项新特性解决了这一问题.
在某些情况下, 比如当被调用的是严格模式的函数时, 既不使用参数也不使用 REST 参数, 这时候就完全不需要去进行参数自适应. 现在 V8 在这种情况下就直接跳过这一自适应过程, 将调用开销减少了超过 60%.
改进了原生访问器性能
Angular 团队发现, 在 Chrome 中直接通过各自的 get 函数调用 DOM 属性访问器之类的原生访问器, 比单态 (monomorphic) 甚至是综合态 (megamorphic ) 属性访问要慢得多. 这是因为在 V8 中使用慢速路径通过 Function#call() 调用 DOM 访问器, 而不是已经存在属性访问的快速路径.
此版本中提高了调用原生访问器的性能, 使其比综合态属性访问快得多, 效果如下:
解释器性能
在 Chrome 中, 下载大脚本时是在 worker 线程上以流进行解析的, 此版本修复了一个源流中用自定义 UTF-8 进行解码的问题, 修复后使得流式解析性能平均快了 8%.
还在 V8 预解析器中发现了另一个问题: worker 线程中属性名被不必要地重复. 删除这些重复数据后将流式解析器性能提高了 10.5%.
内存减少
字节码 flush
从 JavaScript 源码编译的字节码占据了很大一部分 V8 堆空间, 通常约为 15%, 包括相关的元数据. 但是有许多函数只在初始化期间执行, 或者在编译后很少使用, 这显然是一种浪费.
为了减少 V8 的内存开销, 此版本实现了一项字节码 flush 新功能, 即如果已编译的字节码最近没有被执行, 那么在 GC 期间将从函数中将其清除. 为了实现这一点, V8 会跟踪函数节码的年龄, 在 GC 期间递增年龄, 并在执行函数时将其重置为零. 任何超预设 "老化阈值" 的字节码的内存都会被下一个垃圾回收器收走, 并且如果将来再次执行该函数, 它将重新编译其字节码.
该字节码 flush 功能为 Chrome 用户节省了大量内存, 将 V8 堆中的内存量减少了 5-15%, 同时不会降低性能或显着增加编译 JavaScript 代码所花费的 CPU 时间.
此外还有 JavaScript 私有类字段, V8 API 等改进, 详情查看发布公告 https://v8.dev/blog/v8-release-74 .
来源: http://news.51cto.com/art/201903/593933.htm