javascript
JavaScript 引擎和 Just-in-Time 编译概念,Hot Function 的简单介绍
原文:JavaScript engines and Just-In-Time compilation: A beginner’s exploration, part 1
JavaScript 引擎本身也是一種軟件,它將您華麗的 JavaScript 代碼行轉換為我們的機器可執行的二進制代碼。
所有主要瀏覽器都開發了自己的 JavaScript 引擎。 Chrome 有 V8,Firefox 運行 SpiderMonkey(第一個 JavaScript 引擎的進化產品,由 Brendan Eich 在 90 年代為 Netscape Navigator 開發),Microsoft Edge 有 Chakra,Safari 有 Nitro。 Node.js 建立在 Chrome 的 V8 引擎之上。 物聯網設備也可以有一個 JavaScript 引擎。
每個 JavaScript 引擎都負責使用 Ecma International 的 TC39 制定的 ECMAScript 規則和標準。
Why modern JavaScript engines do Just-In-Time compilation
JavaScript 是一門動態類型語言。
let x = 8 let y = "Henlo fren"這意味著無論何時你在 JavaScript 中聲明一個變量,你都不必明確說明變量 x 存儲的信息類型。 JavaScript 引擎在執行源代碼時檢查類型。
在靜態類型語言(如 C++)中聲明變量時,您必須顯式指定變量值的類型。
int x = 8 string y = "Henlo fren"有了如此嚴格的規則,靜態類型語言可以具有更高的學習曲線。在嘗試編寫一個簡單的程序之前,您必須更多地了解它的規則和類型。
然而,從編譯器的角度來看,靜態類型語言允許更快的性能。預先,當編譯器開始將代碼轉換為可執行的機器代碼二進制時,該語言為編譯器提供了大量有關源代碼的信息。
另一方面,像 JavaScript 這樣的動態類型語言很少向編譯器提供有關其類型的信息。這為編譯器在生成機器代碼之前創建了另一層工作,使其執行速度比靜態編寫語言的編譯慢。
But fear not, this is where Just-In-Time compilation comes in!
最初開發 JavaScript 時,它旨在編寫少量用于增強網頁的腳本。隨著開發人員開始構建和使用更多 JavaScript 框架和庫,以及發出 AJAX 請求,對更好、更快性能的需求不斷增長。
當 Chrome 于 2008 年推出時,谷歌還首次發布了其 V8 引擎,這是現代 JavaScript 引擎中的第一個。 V8 的主要特性之一是即時編譯 - Just-In-Time compilation。
在 Ahead-of-Time 編譯中,編譯過程必須在系統運行可執行機器代碼之前完成。有了 Just-In-Time compilation 這一新特性,V8引擎會根據需要編譯源代碼,在執行編譯過程生成的機器碼時收集類型信息,然后根據執行過程收集的信息重新編譯源代碼。兩個進程之間的來回加快了執行過程的性能。
為了讓 JavaScript 在動態類型的情況下仍能以最快的速度運行,JavaScript 引擎有一些巧妙的技巧。
像大多數現代 JavaScript 引擎一樣,V8 有兩個編譯器:基線 (baseline)編譯器和優化編譯器。
當 V8 編譯你的 JavaScript 代碼時,它的解析器會生成一種叫做抽象語法樹的東西。Ignition,V8 的基線編譯器或解釋器,從這個語法樹生成字節碼。 Ignition 忠實于它的即時編譯特性,它編譯 JavaScript 代碼,運行它,編譯它,運行它,來回,一遍又一遍。
在運行時,字節碼被分析,引擎識別可以重新編譯以獲得最佳性能的部分(“熱函數”),將該代碼發送到 TurboFan,它是 V8 的優化編譯器。正是因為即時編譯,引擎才能夠因為即時編譯而識別這些所謂的“熱功能”。
The + operator and V8 optimization
在她的精彩演講 JavaScript 引擎中,V8 工程師 Franziska Hinkelmann 使用 + 運算符來解釋 V8 的優化是如何工作的。
乍一看,加法運算符可能看起來很簡單,任何編譯器都可以編譯和執行。 但是,如果您查看 Ecma 規范,在程序實際添加任何內容之前,引擎實際上需要執行很多步驟:
這些步驟中的每一步都在調用其他函數,而這些函數又可能調用其他函數,依此類推。所有引擎都必須遵循這些 Ecma 規范,因此 JavaScript 不僅僅是無法無天的。
因此,當您的程序有一個將兩個整數相加的函數時,當您第一次調用該函數時,JavaScript 引擎會費力地完成這些步驟中的每一步,最終將您的兩個整數相加。當它通過 JIT 過程(編譯、運行、編譯、運行、編譯等)時,它意識到你的函數很熱,很熱,很熱,因為你一直在調用它。從引擎在運行時收集的信息,它也意識到這個特定函數使用的數據類型只是整數。有了這些信息,V8 將您的代碼發送到 TurboFan,它的優化器編譯器,它為您的函數生成更好的機器代碼。下次您再次調用該函數時,它會跳過冗長的 Ecma 步驟,您的函數將運行得更快。
但是當您決定在調用該函數時連接一些字符串而不是添加兩個整數時會發生什么? V8 將該函數拋出到去優化器,將其發送回 Ignition,然后 Igntion 再次執行那些 Ecma 指定的步驟來運行該函數。
更多Jerry的原創文章,盡在:“汪子熙”:
總結
以上是生活随笔為你收集整理的JavaScript 引擎和 Just-in-Time 编译概念,Hot Function 的简单介绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 斐讯n1进入u盘启动
- 下一篇: 如何找到 SAP Spartacus 里