2013-03-02 12 views
10

Questo può sembrare un punto particolarmente oscuro, tuttavia sto tentando di migliorare il mio radicamento nella lingua Javascript nel suo insieme (in particolare le sue migliori e più efficienti pratiche).Perché la definizione delle funzioni del prototipo JS è più rapida rispetto a un dizionario?

Mentre testare una teoria in http://jsperf.com/ mi si avvicinò con alcuni risultati strani:

Supponiamo di avere due prototipi "identici", definiti come segue:

Object1

var Object1 = function() {} 

Object1.prototype.defaults = { 
    radius: 400, 
    up: 1 
} 

Object1.prototype.centerOffset = function() { 
    return this.defaults.radius*this.defaults.up; 
} 

Object2

var Object2 = function() {} 

Object2.prototype = { 
    defaults: { 
     radius: 400, 
     up: 1 
    }, 

    centerOffset: function() { 
     return this.defaults.radius*this.defaults.up; 
    } 
} 

Object1 ha un consistente (se marginale: ~ 3%) la velocità vantaggio rispetto Object2 quando si eseguono le seguenti semplici operazioni:

var o = new Object1(); 
var offset = o.centerOffset(); 

&

var o = new Object2(); 
var offset = o.centerOffset(); 

È possibile eseguire i test te stesso here. Sto usando Chrome 25 su OSX 10.6.8.

Quello che vorrei sapere è questo:

  • Qual è la ragione (s) di questa differenza di prestazioni?
  • Questa performance è indicativa di alcune buone pratiche in javascript?

Grazie in anticipo ragazzi.

EDIT: Grazie per le risposte - come alcuni hanno menzionato, ulteriori test da parte mia sembrano suggerire che questo problema è browser (o piuttosto, compilatore JavaScript specifico). Ho testato anche in Safari, IE 10 e Firefox. IE 10 e Firefox hanno entrambi dato risultati così vicini da non essere diversi. Safari ha eseguito le operazioni su Object2 leggermente più velocemente di quelle su Object1 (circa il 2% in media). Mi piacerebbe sapere qual è il valore anomalo (Altro), poiché la differenza di prestazioni in quel caso sembra essere sostanziale.

+0

Probabilmente è solo indicativo di qualche stranezza del V8. – delnan

+0

Ho avuto il risultato opposto eseguendo firefox –

+0

Affascinante, quindi il suo compilatore specifico ... Farò qualche altro test del browser e riferirò. –

risposta

3

Quando si dichiara una funzione, il suo attributo prototipo viene inizializzato con un oggetto contenente un costruttore predefinito.

Con Oggetto1, si aggiunge un attributo alla funzione prototipo esistente. Con Object2, si sostituisce il prototipo esistente con un proprio costruttore.

I due non sono identici.

Perché le velocità sono diverse? Bene, V8 potrebbe aggiungere una funzione di costruzione al prototipo object2 ogni volta che crei un'istanza.

O più probabilmente, la funzione di prototipo preesistente è implementata in codice macchina per renderla più veloce e quando si assegna il proprio oggetto a Object2.prototype, la funzione prototipo è ora javascript puro e quindi più lenta.

I dettagli non sono così importanti, perché diversi interpreti lo gestiranno diversamente, l'importante è rendersi conto che Object1 e Object2 non sono esattamente identici.

+0

Mi piace la tua risposta. Non avevo considerato la possibilità di un'ottimizzazione dell'implementazione che stavo ignorando. –

+0

Ho accettato la tua risposta perché offriva chiarimenti su cosa esattamente stavo chiedendo. Sospetto che per capire veramente i particolari di ciò che sta accadendo qui avrei bisogno di rispolverare le mie abilità in C++ e dare un'occhiata al sorgente Chromium/V8. –

0

Penso che abbia qualcosa da fare con l'aggiunta del prototipo in Object1 e la sovrascrittura in Object2. Per verificare, ho fatto un secondo esempio di performance: http://jsperf.com/correct-way-to-declare-prototype-functions/2

Lì ho aggiunto "Object1.prototype = {}" prima che le funzioni vengano assegnate. Le prestazioni ora sono circa uguali tra Object1 e Object2 (almeno in chrome).

Problemi correlati