問答方式學 Node.js

Q: 什麼是 Node.js ?

A:Node.js 是指運於 web 服務端的 JavaScript,基於 Chrome V8 引擎,有非阻塞,事件驅動 I/O 等特性。javascript

Q: 等等,你剛提到了 Chrome V8 引擎,它是什麼,爲何使用它而不是其它引擎?

A:JavaScript 引擎是執行 JavaScript 代碼的程序或解釋器,JavaScript 引擎能夠實現爲標準解釋器,或者以某種形式將 JavaScript 編譯爲字節碼的即時編譯器。它的工做流程大體以下:java

Chrome V8 引擎即是其中一種,由 Google 開發,使用 C++ 編寫,它的工做流程幾乎與上圖一致:git

相比於其它 JavaScript 引擎轉換成字節碼或者解釋執行,V8 將 JavaScript 代碼轉換成更高效的機器碼(IA-32, x86-64, ARM, or MIPS CPUs)。它經過 JIT(Just-In-Time)編譯器實現,不生成字節碼或任何中間代碼。而且使用瞭如 Inlining、Shapes、Inline Caches 等方法來提升性能。github

Q:很好,如今我已經瞭解一點 Chrome V8 引擎有什麼用了,可是你列舉的那些方法,真讓我頭大。

A:好比 Shapes 與 Inline Caches 用來優化對象屬性加載。web

Q:嗯?

A:ECMAScript 規範基本上將全部對象定義爲由字符串鍵值映射到 property 屬性的字典,其中 [[]] 雙方括號是規範定義不能直接暴露給 JavaScript 的屬性的表示方法。session

Q:在內存中也是這麼存儲?

A:不不不,若是在內存中這麼存儲,那就浪費空間了。好比說有相同形狀的對象 object = { x: 7, y: 8 },它們的屬性名是相同的,而且在屬性值的完整字典中,也只有 [[value]] 不一樣。ide

Q:那應該分開存儲,把除 [[value]] 以外的全部屬性名和其他特性單獨存儲。而且它須要有一個屬性,來告知 JavaScript 引擎去哪查找具體的值。

A:是的,引擎將對象的 Shape 分開存儲,以下 JSObject 只是存儲 [[value]]Shape 中有一個 Offset 偏移量來告知 JavaScript 取哪找具體的值:函數

當有多個具備相同形狀對象時,優點變得清晰可見。由於只須要將它們的形狀與鍵值屬性信息存儲一次!性能

Q:原來是這樣,不過那和 Inline Caches 有什麼關係?

A:關係大了,Shapes 主要是用來實現 Inline Caches(ICs)的,Inline Caches 是 JavaScript 快速運行的關鍵因素之一。優化

Q:

A:好比有一個從對象中獲取 x 屬性的函數,在 JSC(JavaScriptCore) 中執行時,會生成如下字節碼:

Inline Caches 在第一個指令 get_by_id 指令中,由兩個未初始化的插槽組成。

當調用函數 getX({ x: 'a' }) 時,像前面所說,對象 { x: 'a' } 有一個包含屬性 x 的 Shape,該 Shape 包含屬性 x 的偏移量和其它特性,當第一次執行該函數時,會把該屬性的 Shape 和 偏移量存儲在 Inline Caches 中:

後續調用該函數時,Inline Caches 只須要對比 Shape,若是與之前相同,則只須要從偏移量加載該屬性值。這比每次查找要快不少。

Q:很精彩!

A:V8 所作的,遠不止這些,在即將要發佈的 7.2 版本中,解析時間明顯下降,縮短加載時間,提升響應速度:

Q:好了,我們不說 V8 了,我對你前面提到的非阻塞和事件驅動 I/O 挺感興趣的。

A:......

未完待續

參考

相關文章
相關標籤/搜索