2013-07-24 21 views
11

Ho letto alcuni articoli sulle classi nascoste del V8. Tuttavia, ho ancora alcune domande nella mia testa:Cancellare il concetto di `classi nascoste` di V8

Se, diciamo, ci sono due oggetti:

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

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

vanno a finire con la stessa classe nascosto o separato solo perché uno è andato 0 + x + y e l'altro 0 + y + x? Come ho capito, ottengono classi diverse, ma voglio solo assicurarmi di averlo capito.

allora, abbiamo questo caso:

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 
} 

fare si finisce con la stessa classe di nascosto? Potrei supporre che a, b e c, ma non lo sia lo d. A meno che non ci sia un certo ordinamento su tali espressioni oggetto (analogamente alla breve dichiarazione dell'array che viene analizzata per il tipo).

Infine, abbiamo questo:

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) 

È sorta simile al secondo caso. Questi oggetti sembrano gli stessi eccetto che la loro origine (instanceof...) è diversa. Tuttavia, ci gli oggetti finiscono con la stessa classe nascosta?

+1

Javascript non ha classi. Le classi nascoste non sono concetti, sono dettagli interni dell'implementazione. A meno che tu non voglia incidere v8 o altre macchine virtuali che devono risolvere problemi simili, non ti interessa. –

+3

Mi interessa davvero le prestazioni del codice che scrivo. Ho sperimentato me stesso che è più semplice preoccuparsi delle prestazioni * come si va * piuttosto che preoccuparsi di ciò quando qualcuno si lamenta che funziona troppo lentamente. – Pijusn

+0

Ci sono aspetti delle prestazioni che devi davvero preoccuparti mentre vai. Come scegliere algoritmi ottimali, memorizzare nella cache i dati necessari spesso e così via. Ma se hai davvero bisogno di preoccuparti delle prestazioni a questo livello, non dovresti probabilmente usare JavaScript in primo luogo. –

risposta

14

Se si scarica V8 e si crea la versione di debug, è possibile passare tali oggetti casualmente a una funzione in un ciclo infinito e stampare lo smontaggio ottimizzato e verificare se sono stati considerati come aventi la stessa classe.

Nel primo caso hai ragione che avranno classi nascoste diverse.


Nel secondo caso si sbaglia, si finirà con 4 classi diverse, quindi nessuno di loro condivide una classe.

In primo luogo, i campi che vengono aggiunti a un oggetto all'esterno del costruttore o dell'oggetto letterale, non verranno archiviati direttamente su sull'oggetto ma in un array esterno all'oggetto. Ecco perché b avrà una classe nascosta diversa da tutti.

Un costruttore univoco costruirà oggetti di classe unica, quindi a avrà una classe nascosta diversa da tutti. I valori letterali dell'oggetto hanno proprietà in ordine diverso, che è lo stesso del primo caso.

Tuttavia oggetto letterali con esattamente lo stesso layout condivideranno una classe nascosta, quindi se abbiamo aggiunto oggetto e:

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

Poi c sarebbe condividere stessa classe nascosta con e.


Nel terzo caso essi avranno diverse classi nascosti per la stessa ragione come nel secondo caso, i costruttori unici costruire oggetti di varie classi.


Si potrebbe anche trovare questo interessante https://codereview.stackexchange.com/a/28360/9258

+0

Qual è il grosso problema di avere ** stessa classe nascosta **? Potresti per favore spiegare? – TrungDQ

+1

Si tratta di prestazioni in quanto l'ottimizzatore gestisce i siti di codice in modo diverso a seconda di quali classi nascoste devono essere supportate. Se, ad esempio, in una particolare riga di codice, un particolare argomento ha sempre la stessa classe nascosta, la chiamata può essere considerata monomorfica che consente [molto più aggressivo il caching in linea] (http://en.wikipedia.org/wiki/Inline_caching # Monomorphic_inline_caching) e altre strategie di ottimizzazione. – Domi

5

Si può facilmente verificare utilizzando shell di debug del V8 d8.

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

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

print(%HaveSameMap(a, b)); 

Quindi eseguire

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

si otterrà i risultati attesi:

false 

Per voi secondo esempio:

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

Tutti i 4 oggetti hanno diverse classi nascoste :

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

E, ultimo ma non meno importante:

// 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 e b hanno diverse classi di nascosto, ma b e c lo stesso.

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