2013-07-24 60 views
11

我讀過一些關於V8隱藏類的文章。不過,我仍然有我的頭幾個問題:清除V8的隱藏類概念

如果,比方說,有兩個對象:

var a = { } 
a.x = 5 
a.y = 6 

var b = { } 
b.y = 7 
b.x = 8 

難道他們結束了同一個隱藏類或分開只是因爲一個人去0 + x + y和另一個0 + y + x?據我瞭解,他們得到不同的班,但只是想確保我得到了它。

然後,我們有這樣的情況:

function Point(x, y) { 
    this.x = x 
    this.y = y 
} 
var a = new Point(7, 8) 

var b = { } 
b.x = 6 
b.y = 8 

var c = { 
    x: 8, 
    y: 9 
} 

var d = { 
    y: 9, 
    x: 80 
} 

難道我們結束了同一個隱藏類?我可能猜到a,bc做但d沒有。除非在這樣的對象表達式上進行了一些排序(類似於針對該類型分析的數組的短聲明)。

最後,我們有這樣的:

function PointA(x, y) { 
    this.x = x 
    this.y = y 
} 
var a = new PointA(7, 8) 

function PointB(x, y) { 
    this.x = x 
    this.y = y 
} 
var b = new PointB(7, 8) 

是八九不離十類似第二種情況。除了它們的來源(instanceof...)不同之外,這些對象似乎相同。但是,那裏的對象最終是否有相同的隱藏類?

+1

Javascript沒有課程。隱藏的類不是概念,它們是實現的內部細節。除非你想破解v8或其他需要解決類似問題的虛擬機,否則你並不在意。 –

+3

我其實關心我寫的代碼的性能。我經歷過我自己,當你走的時候關心表現*而不是在有人抱怨跑步速度太慢時關心它會更簡單。 – Pijusn

+0

有些方面的表現,你確實需要關心,因爲你去。就像選擇最佳算法一樣,緩存你經常需要的數據等等。但是如果你真的需要關心這個級別的性能,那麼你不應該首先使用JavaScript。 –

回答

14

如果您下載V8並構建調試版本,您可以隨機將這些對象傳遞給無限循環中的函數,並打印出優化的反彙編代碼,並查看它們是否被視爲具有相同的類。

在第一種情況下,你是對的,他們會有不同的隱藏類。


在第二種情況下,你錯了,你最終會得到4個不同的類,所以他們都沒有共享一個類。首先,添加到構造函數或對象文本外的對象的字段不會直接存儲在對象上,而是存儲在對象外部的數組中。所以這就是爲什麼b將有不同於每個人的隱藏課程。

一個獨特的構造函數將構造唯一類的對象,因此a將有不同於每個人的隱藏類。對象 文字具有與第一種情況相同的不同順序的屬性。

但是反對文字完全相同的佈局將共享一個隱藏的類,所以如果我們添加的對象e

var e = { 
    x: 32, 
    y: -15 
}; 

然後c將與e共享同一個隱藏的類。


在第三情況下,它們將具有不同的隱藏的類相同的理由,在第二種情況下,唯一的構造 構造不同類的對象。


您也可能會發現這個有趣的https://codereview.stackexchange.com/a/28360/9258

+0

有**相同的隱藏類**有什麼大不了?你能解釋一下嗎? – TrungDQ

+1

這完全是關於性能的,因爲優化器根據需要支持哪些隱藏類來不同地處理代碼網站。例如,如果在特定的代碼行中,某個特定的參數總是具有相同的隱藏類,則該調用可以被認爲是單形的,這允許[更積極的內聯緩存](http://en.wikipedia.org/wiki/Inline_caching#Monomorphic_inline_caching)和其他優化策略。 – Domi

5

您可以輕鬆地通過使用V8的調試外殼d8檢查。

// test1.js 
var a = { } 
a.x = 5 
a.y = 6 

var b = { } 
b.y = 7 
b.x = 8 

print(%HaveSameMap(a, b)); 

然後運行

$ d8 --allow-natives-syntax test1.js 

你會得到預期的輸出:

false 

對於你第二個例子:

//test2.js 
function Point(x, y) { 
    this.x = x 
    this.y = y 
} 

var a = new Point(7, 8) 

var b = { } 
b.x = 6 
b.y = 8 

var c = { 
    x: 8, 
    y: 9 
} 

var d = { 
    y: 9, 
    x: 80 
} 

print(%HaveSameMap(a, b)); 
print(%HaveSameMap(b, c)); 
print(%HaveSameMap(b, d)); 
print(%HaveSameMap(c, d)); 

所有4個對象有不同的隱藏類:

$ d8 --allow-natives-syntax test2.js 
false 
false 
false 
false 

最後但並非最不重要的:

// test3.js 
function PointA(x, y) { 
    this.x = x 
    this.y = y 
} 
var a = new PointA(7, 8) 

function PointB(x, y) { 
    this.x = x 
    this.y = y 
} 
var b = new PointB(7, 8) 
var c = new PointB(1,4) 

print(%HaveSameMap(a, b)); 
print(%HaveSameMap(b, c)); 

ab有不同的隱藏的類,但bc相同。

$ d8 --allow-natives-syntax test3.js 
false 
true