上周, JavaScript 引擎「V8」的开发团队在该项目官方网站上正式宣布推出最新的 8.0 版本. 这次更新的重点主要集中在错误修复及性能改善上, 正式的版本将在数周后随着谷歌 Chrome 80 稳定版一起发布.
V8 是谷歌公司推出的开源高性能 JavaScript 引擎, 主要用于提升 web 浏览器内部 JavaScript 脚本执行的性能. V8 通过 C++ 语言编写, 主要用在 Chrome 浏览器以及 Node.JS 上, 实现了对 ECMAScript 与 WebAssembly 的支持, 可运行于 Windows 7,macOS 10.12 以及使用 x64,IA-32,ARM,MIPS 处理器的 Linux 系统, 或更新版本的操作系统环境下. V8 既可以单独运行, 也能够内嵌到任何基于 C++ 的应用中. V8 项目开发至今已拥有超过 11 年的历史.
性能
指针压缩
V8 引擎的这次更新, 对内存占用量与速度都进行了优化. V8 堆包含了很多东西, 例如浮点值, 字符串字符, 编译代码以及标定值, 开发团队发现这些标记值占据了堆的很大一部分空间.
标定值与系统指针一样大, 32 位宽度对应 32 位架构, 64 位宽度对应 64 位架构. 当开发团队对比 32 位版本与 64 位版本时发现, 每个标记值使用了两倍的堆内存.
因为高位可以由低位合成, 所以只需要将唯一的低位存储到堆中就能实现降低内存的占用量, 平均可节省 40% 堆内存, 这一方法被称为「指针压缩」.
通常情况下, 在优化内存占用的同时也会牺牲部分性能, 但经过这一改进之后, 在 V8 及其垃圾收集器中却出现了真实网站的性能提升.
优化高阶内建
在优化高阶内建上, 新版本解除了 TurboFan 优化流程中的一处限制, 这处限制使高阶内建无法得到优化.
- const charCodeAt = Function.prototype.call.bind(String.prototype.charCodeAt);
- charCodeAt(string, 8);
到目前为止, 对 charCodeAt 的调用对 TurboFan 来说是完全不透明的, 从而引发了对用户定义函数通用调用. 通过这一改变, 现在可以识别出实际上是在调用内置 String.prototype.charCodeAt 函数, 从而能够触发 TurboFan 库中的进一步优化来改善对内建的调用, 进而获得与以下相同的性能:
string.charCodeAt(8);
这一变化也会影响到其他一些内建, 比如 Function.prototype.apply,Reflect.apply, 以及很多其他的高阶数组内建.
JavaScript
新版本在 JavaScript 方面出现了两个新特性 ── 可选链和 null 判断合并.
可选链
在编写属性访问链时, 程序员经常需要检查中间值是否为空. 没有经过错误检查的链可能会扔出, 而经过了明确的错误检查的链是冗长的, 并且会产生不必要的结果, 即检查所有的真实值, 而不是只检查非空值.
// Error prone-version, could throw.const nameLength = db.user.name.length;// Less error-prone, but harder to read.let nameLength;if (db && db.user && db.user.name) nameLength = db.user.name.length;
可选链 (?.) 允许程序员编写更精炼, 鲁棒性更强的属性访问链, 检查中间值是否为空. 如果中间值为空, 则整个表达式的计算结果为未定义的.
// Still checks for errors and is much more readable.const nameLength = db?.user?.name?.length;
除了静态属性访问外, 动态属性访问和调用也能得到支持.
null 合并
null 合并操作符 ?? 是一个新的用于处理默认值的短路二进制操作符. 目前, 默认值有时由逻辑 || 操作符处理, 如下所示:
function Component(props) { const enable = props.enabled || true; // ...}
对 || 的使用, 并不适合计算默认值, 因为当 a 为非真时 a || b 的结果为 b. 如果 props.enabled 明确被设置为假, 那么 enable 仍然为真.
通过 null 合并操作符, 当 a 为空时, a ?? b 的结果为 b, 否则结果为 a. 这是理想的默认值行为, 并使用 ?? 修正了之前提到的错误.
function Component(props) { const enable = props.enabled ?? true; // ...}
null 合并操作符与可选链是相伴而生的特性, 可协同工作. 当没有任何 props 参数传入时, 它们可以对示例进行进一步修改以作为应对.
function Component(props) { const enable = props?.enabled ?? true; // ...}
V8 应用程序接口
请通过「Git log branch-heads/7.9.. ..branch-heads/8.0 include/v8.h」指令来获得接口变化列表.
开发人员目前可通过指令「Git checkout -b 8.0 -t branch-heads/8.0」来体验 V8 引擎 8.0 版本中的新特性.
相关项目地址:
高性能 JavaScript 引擎 V8 官方网站 https://v8.dev/
高性能 JavaScript 引擎 V8 GitHub 地址 https://github.com/v8/v8
来源: https://segmentfault.com/a/1190000021373691