2013-03-25 128 views
2

當我看進v8 design elements of fast property access,它提到了這個主題的最後一段了這一點:JavaScript引擎V8快速訪問屬性

有兩個優點,使用隱藏的類:屬性訪問並 不需要字典查找,並且它們使V8能夠使用經典的基於類的優化 內聯緩存。

這對我來說有點模糊。任何人都可以詳細說明爲什麼隱藏類不需要字典查找,並啓用V8使用經典的基於類的優化,內聯緩存?

請儘可能詳細地做到這一點。

+3

「任何人都可以詳細說明爲什麼隱藏類不需要字典查找」---因爲這裏沒有字典。請再次閱讀「快速訪問」部分 – zerkms 2013-03-26 02:06:16

+0

@Bergi:https://developers.google.com/v8/design – zerkms 2013-03-26 02:06:40

回答

3

我認爲隱藏類的想法你提到的文章中進行了很好的解釋。無論何時將新屬性添加到對象時,都會創建一個新的隱藏類。該對象保持對這個隱藏類的引用。此外,隱藏類也保持到先前創建的隱藏類的引用。例如:

function Point(x, y) { 
    this.x = x; 
    this.y = y; 
} 

var point = new Point(10, 10); 

new Point()被稱爲新隱藏類被創建,並point保持到是隱藏類的引用。那最初隱藏類是空的,也就是說,它不包含任何屬性。然後,當調用this.x時,將創建一個新的隱藏類。這個隱藏的類保持對前一個隱藏類的引用,並且更新其對該新的隱藏類的引用。執行this.y = y時會再次發生。

由於在JavaScript中可以向對象添加和刪除屬性,因此解決屬性訪問的方法是使用地圖。在另一方面,隱藏類存儲屬性直線,一個接一個,像在C.由於一個結構隱藏類,訪問屬性是儘可能快地訪問數組的元素。

現在讓我們來看看什麼內嵌的緩存手段。內聯緩存是一種古老的優化技術,用於動態語言,如Smalltak 80或Self,並通過JavaScript進行推廣。當在運行時訪問屬性時,有必要確定調用對象的類型,以便準確知道要調用的實現代碼。這就是所謂的動態派遣後期綁定,並且是在JavaScript訪問屬性或兩個操作數總結的時候,當發生了什麼(他們可能是整數等)。請看下面的代碼:

var x = 10; 
var y = 10; 
var total = x + y; 

當使用內嵌的緩存,當var total = x + y編譯,你不要在過程調用到一個通用的另外子程序編譯。相反,該代碼被編譯爲存根(內聯高速緩存)。在內聯高速緩存中生成的代碼將查看收到的參數的類型並生成專用於這些類型的代碼。稍後,如果調用另一個添加,則假定類型將與以前相同,將執行內聯高速緩存。可能會發生類型不同,因此內聯高速緩存所做的第一件事是檢查參數的類型。如果類型不同導致緩存未命中,併爲這些特定類型生成新代碼。如果內聯高速緩存可以處理稱爲多態內聯高速緩存的多種不同類型(其中一個包含多個類型的條目)。

內聯緩存保存了函數調用中推斷參數類型的計算,如果調用發生在循環內部,則它們的好處更大。

內嵌的緩存發生在JavaScript中,同時訪問一個對象的屬性,在此之前我們看到隱藏類如何幫助我們,以便快速訪問屬性。

更多有關隱藏類直列緩存我推薦以下相關文章(特別是前兩個,從V8黑客維亞切斯拉夫·葉戈羅夫):