JS 引擎V8 發布v7.4 性能再次大幅提高
JavaScript引擎V8發布了7.4版本,目前處於beta階段,正式版將於幾個星期後與Chrome 74 Stable一起發布。此版本帶來了一些新特性,並極大提升了性能。V8現在不需要運行時分配可執行內存就可以執行JavaScript。
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等改進,詳情查看發佈公告。