2013-07-24 9 views
11

Czytałem kilka artykułów na temat ukrytych klas V8. Jednak mam jeszcze kilka pytań w mojej głowie:Usuwanie górę `ukryte koncepcję classes` V8

Jeśli, powiedzmy, istnieją dwa obiekty:

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

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

Czy oni w końcu z tej samej ukrytej klasy lub oddzielają tylko dlatego, że ktoś poszedł 0 + x + y i drugi 0 + y + x? Jak zrozumiałem, dostają różne klasy, ale chcą się upewnić, że je dostałem.

Następnie mamy tę sprawę:

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 
} 

Wykonaj to w końcu z tej samej ukrytej klasy? Mogę się domyślać, że a, b i c zrobić ale d nie. O ile nie dokonano sortowania na takich wyrażeń obiektowych (podobnie jak w przypadku krótkiej deklaracji tablicy analizowanej dla typu).

Wreszcie mamy to:

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) 

to coś podobnego do drugiej sprawy. Obiekty te wydają się takie same, z wyjątkiem tego, że ich pochodzenie (instanceof...) jest inne. Czy jednak obiekty kończą się tą samą ukrytą klasą?

+1

Javascript nie ma zajęć. Ukryte klasy nie są koncepcją, są wewnętrznymi szczegółami implementacji. Jeśli nie chcesz hackować v8 lub innej wirtualnej maszyny, która musi rozwiązać podobny problem, nie obchodzi cię to. –

+3

Dbam o wydajność kodu, który piszę. Sam doświadczyłem, że łatwiej jest dbać o wydajność * niż o to chodzi * niż dbać o to, gdy ktoś narzeka, że ​​działa zbyt wolno. – Pijusn

+0

Istnieją aspekty wydajności, które naprawdę trzeba dbać w trakcie podróży. Podobnie jak przy wyborze optymalnych algorytmów, często potrzebne są dane buforowania i takie. Ale jeśli naprawdę musisz zadbać o wydajność na tym poziomie, prawdopodobnie nie powinieneś prawdopodobnie używać JavaScriptu. –

Odpowiedz

14

Jeśli pobierzesz V8 i zbudować wersję debugowania można przekazać te obiekty losowo do funkcji w nieskończonej pętli i mieć go wydrukować zoptymalizowaną demontaż i zobaczyć, czy były one traktowane jako mające tę samą klasę.

W pierwszym przypadku masz rację, że będą one mieć różne ukryte klas.


W drugim przypadku nie masz racji, skończy się z 4 różnych klas, więc żaden z nich nie dzielić klasę.

Po pierwsze, pola dodawane do obiektu poza konstruktorem lub literałem obiektu nie będą przechowywane bezpośrednio na obiekcie, ale w tablicy znajdującej się na zewnątrz obiektu. Dlatego b będzie miał inną ukrytą klasę od wszystkich.

Wyjątkowy konstruktor wybuduje obiekty wyjątkowej klasy, więc a będzie miał inną ukrytą klasę od każdego. Gdy obiekt literałami mają właściwości w dowolnej kolejności, która jest taka sama jak w przypadku pierwszego przypadku.

Jednak sprzeciw literały z dokładnie takim samym układzie będą dzielić ukrytą klasy, więc jeśli dodaliśmy obiekt e:

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

Następnie c by dzielić tę samą klasę z e ukryty.


W trzecim przypadku będą mieć różne ukryte zajęcia dla tego samego powodu jak w drugim przypadku, unikalne konstruktorzy konstruowania obiektów różnych klas.


Można również znaleźć ten interesujący https://codereview.stackexchange.com/a/28360/9258

+0

Co to za wielka sprawa posiadania ** tej samej ukrytej klasy **? Czy możesz wyjaśnić? – TrungDQ

+1

Wszystko zależy od wydajności, ponieważ optymalizator obsługuje strony kodowe w różny sposób w zależności od tego, jakie ukryte klasy muszą być obsługiwane. Jeśli, na przykład, w konkretnym wierszu kodu, dany argument zawsze ma tę samą ukrytą klasę, wywołanie może być uważane za monomorficzne, co pozwala na [znacznie bardziej agresywne buforowanie w trybie bezpośrednim] (http://en.wikipedia.org/wiki/Inline_caching # Monomorphic_inline_caching) i inne strategie optymalizacji. – Domi

5

Można łatwo sprawdzić za pomocą V8 debugowania skorupę d8.

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

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

print(%HaveSameMap(a, b)); 

Następnie uruchom

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

Musisz uzyskać oczekiwany wynik:

false 

Dla ciebie drugi przykład:

//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)); 

Wszystkie 4 obiekty mają różne ukryte zajęcia :

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

I last but not least:

// 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)); 

a i b mają różne ukryte klas, ale b i c tak samo.

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