Categories
程式開發

V8 8.0 JavaScript引擎降低堆內存40%,添加語言特性Optional Chaining和Null Coalescing


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)兩種有用語言特性的支持。

可選鏈技術意在簡化屬性值的依次訪問運算。由於一些中間對像是nullundefined,運算存在拋出異常的風險。例如,在下面的代碼中,為避免發生上述問題,需預先檢查所有需訪問的中間屬性是經過良好定義的:

if (resource && resource.address && resource.address.types)  return resource.address.types.length

使用可選鏈操作符?.,該代碼可替換為如下代碼。其中確保了一旦中間組件出現nullundefined等問題,整體表達式立刻做出短路處理:

return resource?.address?.types?.length

對於空合併操作符??,在如下代碼的使用場景中,進一步優化了操作符||

let iterations = settings.iterations || 4;

||操作符的不足之處在於,上面的代碼中,當所需設置的settings.iterations取值為false(即settings.iterations == 0)時,不能使用||操作符。運算最終依然得到默認值,即4。空合併操作符??將會正確處理這類問題。例如:

let iterations = settings.iterations ?? 4;

上例中,anullundefined時,運算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