Google最新发布了V8 JavaScript引擎V8 8.0,其中使用压缩指针(pointer compression)技术,在不影响性能的情况下实现堆内存占用降低了40%。此外,V8 8.0添加了支持“可选链”(optional chaining)的操作符?.
,以及支持“空合并”(nullish coalescence)的双问号操作符??
。V8 v8.0将正式提供在Chrome 80版本中。
据V8核心成员Leszek Świrski介绍,V8 v8.0对JavaScript标签值(tagged value)做了压缩处理。标签值用于表示指向堆或小整数的指针。对于64位CPU,V8指针并未使用整个64位字节表示,而是仅使用了其中的低位字节,高位字节通过算法合成。V8团队在文档中详细阐述了指针压缩算法,该算法参考了Java等平台目前在用的技术。在InfoQ的访谈中,Świrski阐明V8 v8.0中使用的内存压缩算法去除了内存地址的头32位,强制“压缩”指针到4GB空间中,所有“压缩”指针构成4GB空间内的相对偏移量。在计算完全指针地址时,需要在压缩指针地址上添加基础偏移量。Świrski补充说明,团队计划结合使用多字节字对齐和地址层位偏移的方式,将压缩的堆规模扩展到4GB以外的空间。其算法的基本理念是将内存地址逻辑上组织到多字节字(word)而非字节中。例如,如果使用8字节的字,那么只需将地址表示为从0、7、15、23等开始,因此能够实现地址空间扩展到23*232字节。
V8团队特别指出,压缩指针向全指针的转换本身是非常高速的操作,因此压缩指针技术并未引入额外的性能代价。而另一方面的额外收益是,经压缩的指针使得V8垃圾回收机制更为高效。初步基准测试表明,在Facebook、CNN、Google Maps等网站的实践应用中,V8 v8.0无论是在移动端还是在桌面设备端都表现得更为快速。
从JavaScript语言方面看,V8 v8.0引入了对“可选链”(optional chaining)和“空合并”(nullish coalescence)两种有用语言特性的支持。
可选链技术意在简化属性值的依次访问运算。由于一些中间对象是null
或undefined
,运算存在抛出异常的风险。例如,在下面的代码中,为避免发生上述问题,需预先检查所有需访问的中间属性是经过良好定义的:
if (resource && resource.address && resource.address.types) return resource.address.types.length
使用可选链操作符?.
,该代码可替换为如下代码。其中确保了一旦中间组件出现null
或undefined
等问题,整体表达式立刻做出短路处理:
return resource?.address?.types?.length
对于空合并操作符??
,在如下代码的使用场景中,进一步优化了操作符||
:
let iterations = settings.iterations || 4;
||
操作符的不足之处在于,上面的代码中,当所需设置的settings.iterations
取值为false
(即settings.iterations == 0
)时,不能使用||
操作符。运算最终依然得到默认值,即4
。空合并操作符??将会正确处理这类问题。例如:
let iterations = settings.iterations ?? 4;
上例中,a
是null
或undefined
时,运算a ?? b
取值为b
,否则取值为a
。
V8 v8.0目前依然尚未形成V8稳定发行版,计划在数周后发布在Chrome 80稳定版中。开发人员可使用git checkout -b 8.0 -t branch-heads/8.0
命令获取该版本。
2019年12月23日更新:添加了Leszek Świrski对V8中实际采用的指针压缩算法的阐述。
原文链接:
V8 JavaScript Engine 8.0 Reduces Heap by 40%, Adds Optional Chaining and Null Coalescing
领取专属 10元无门槛券
私享最新 技术干货