讓 V8 提前準備:利用顯式編譯提示加速 JavaScript 啟動
讓 JavaScript 更快速運行是提供響應性網頁應用的關鍵。即使 V8 有先進的優化技術,在啟動期間解析和編譯關鍵 JavaScript 仍然可能成為性能瓶頸。能夠在初始腳本編譯過程中確定需編譯的 JavaScript 函數,有助於加速網頁載入。
讓 JavaScript 更快速運行是提供響應性網頁應用的關鍵。即使 V8 有先進的優化技術,在啟動期間解析和編譯關鍵 JavaScript 仍然可能成為性能瓶頸。能夠在初始腳本編譯過程中確定需編譯的 JavaScript 函數,有助於加速網頁載入。
V8 的終極優化編譯器 Turbofan,是少數採用節點之海 (Sea of Nodes, SoN)的大規模生產編譯器之一。然而,自從大約三年前,我們開始逐步淘汰節點之海,轉而使用更傳統的控制流圖 (CFG) 中間表示 (IR),我們將其命名為 Turboshaft。目前為止,Turbofan 的整個 JavaScript 後端已完全採用了 Turboshaft,而 WebAssembly 在其整個管線中也完全使用了 Turboshaft。Turbofan 的兩個部分仍然使用一些節點之海:內建管線(我們正在逐步用 Turboshaft 替代)以及 JavaScript 管線的前端(我們正用另一個基於 CFG 的 IR,名為 Maglev 替代)。這篇博文將解釋我們放棄節點之海的原因。
在 V8,我們不斷努力提升 JavaScript 的性能。作為這一努力的一部分,我們最近重新審視了 JetStream2 基準測試套件,以消除性能瓶頸。本篇文章詳細介紹了一項具體的優化,它使 async-fs
基準測試達到了顯著的 2.5倍
性能提升,並對整體得分帶來了可觀的增益。該優化受基準測試的啟發,但類似模式也出現在真實世界代碼中。
你是否曾經好奇像 undefined
、true
等核心 JavaScript 物件是從哪裡來的?這些物件是任何使用者定義物件的基本單位,必須先存在。V8 將它們稱為不可移動且不可變的根物件,並將它們存放於自己的堆區——唯讀堆。由於這些物件被頻繁使用,因此快速存取至關重要。而什麼能比在編譯時正確推測它們的記憶體位址更快呢?
歡迎來到令人興奮的 V8 世界,在這裡速度不僅僅是一項功能,而是一種生活方式。當我們向 2023 年告別時,是時候慶祝 V8 今年取得的令人印象深刻的成就了。
通過創新的性能優化,V8 繼續在不斷演變的 Web 領域推進可能性的邊界。我們引入了一個新的中層編譯器,並對頂層編譯器基礎設施、運行時和垃圾回收器進行了多項改進,這些改進帶來了全方位的顯著速度提升。
在 Chrome M117 中,我們引入了一個新的優化編譯器:Maglev。Maglev 位於現有的 Sparkplug 和 TurboFan 編譯器之間,扮演快速生成足夠好的代碼的快速優化編譯器角色。
直到 2021 年,V8 主要有兩個執行層級:Ignition(解釋器);以及 TurboFan,V8 的優化編譯器,專注於峰值效能。所有 JavaScript 代碼首先編譯為 Ignition bytecode,並通過解釋來執行。在執行期間,V8 追蹤程式的行為,包括追蹤物件形狀和類型。執行時的元數據及 bytecode 都會被輸入到優化編譯器中,以生成高效能(通常是投機性的)機器代碼,可以顯著快於解釋器執行。
在 V8 v9.1 中,我們暫時取消在桌面端的內建函式嵌入。雖然嵌入內建函式能顯著改善記憶體使用處理,我們發現嵌入函式與 JIT 編譯程式碼之間的函式呼叫可能帶來顯著的效能損失。此成本會依 CPU 的微架構而異。在本文中,我們會解釋為何這種情況會發生、效能表現如何,以及我們長期規劃的解決方案。
super
關鍵字 可用於訪問物件父級的屬性和函數。
以前,訪問 super 屬性(如 super.x
)是通過執行期呼叫實現的。從 V8 v9.0 開始,我們在未優化的程式碼中重用了內聯快取(IC)系統,並為 super 屬性訪問生成適當的優化程式碼,而無需跳轉到執行期。
由於 Chrome 和 Emscripten 的近期工作,您現在可以在 WebAssembly 應用程式中使用最多 4GB 的記憶體。這比之前的 2GB 限制有所提升。聽起來可能有些奇怪,記憶體的限制似乎本不應該存在——畢竟,使用 512MB 或 1GB 的記憶體並不需要特別的工作!——但事實證明,在從 2GB 跨越到 4GB 的過程中,無論是在瀏覽器還是工具鏈中,都發生了一些特別的變化,我們將在本篇文章中介紹。