2013-03-15 17 views
13

Stavo leggendo lo High Performance Javascript di Nicholas Zackas in cui discute l'ottimizzazione di un ciclo for invertendolo e minimizzando le sue ricerche di proprietà.I nuovi browser ottimizzano i loop in modo diverso?

Invece di:

for (var i = 0; i < items.length; i++) { 
    processItems(items[i]); 
} 

Si ottiene:

for (var i = items.length; i--;) { 
    processItems(items[i]); 
} 

Al momento della scrittura, i tempi di esecuzione sono stati "fino al 50% -60% più veloce rispetto all'originale." Tuttavia ho creato uno jsperf e in Firefox e Chrome ho notato che lo ottimizzato per il ciclo per loop è in realtà notevolmente più lento, specialmente in Firefox.

enter image description here

fare più recente browser ottimizzare per i loop in modo diverso? Il modo più efficace per scrivere un ciclo for ora è semplicemente il modo base?

+0

Strano, ho provato circa lo stesso ieri e il fest uno era il più lento ... –

+11

Sembra pericolosamente vicino alla micro-ottimizzazione per me. –

+0

Per le persone che hanno visto la mia risposta prima ho cancellato: probabilmente era sbagliato e sono troppo incerto su questo per crearne uno nuovo. –

risposta

1

Forse potresti includere anche il caso di test, piuttosto che forzare il browser a trasmettere la risposta a booleano?

var i, arr = [...]; 
for (i = arr.length; i > 0; i -= 1) { arr[i-1] = 1; } 

primo luogo, il ciclo viene colata la 0 come fine condizione, secondo, arr[i] dove i = arr.length è indefinito, il che significa che Chrome de-ottimizzare il ciclo in materia di accesso tale matrice, a causa di tipi impliciti , sotto il cofano di Chrome.

Quindi, per quanto riguarda Chrome, ci sono due grandi de-ottimizzazioni che si verificano nel caso d'uso di Zakas.

I motori JavaScript hanno davvero fatto passi da gigante negli ultimi 3 anni, per quanto riguarda l'ottimizzazione delle cose dietro le quinte. Ora, è meno di scrivere codice per ingannare il motore in un'ottica di ottimizzazione migliore (che ora può essere contro-intuitivo all'ottimizzazione dell'intelligence effettiva incorporata nei compilatori JS dei browser moderni), e altro ancora sulla scrittura di codice ottimizzato nel senso comune - - sapere quali tipi di dati usare, quando, eccetera.

Penso che scoprirai che se proverai di nuovo il test, cambiando queste due cose che consiglio nell'esempio di codice sopra, che mentre i numeri potrebbero non corrispondere esattamente, saranno molto più vicino alle prestazioni avanzate.

+0

In molti casi, si tratta di utilizzare un modello che il JIT può riconoscere. Ad esempio, se il JIT può determinare che la condizione di uscita dal loop contenga un controllo dei limiti, può omettere di eseguire un controllo dei limiti su ogni accesso di array all'interno del ciclo. –

+0

@BenVoigt davvero. L'altra parte non sta uscendo dai limiti degli array, per iniziare con 'i <= arr.length; arr [i]; 'causerebbe un de-op dell'array in Chrome/V8 (non necessariamente altri motori), se' arr' era un array non sparse con numeri interi, o in misura minore, con un solo dato- genere. Colpire che non definito al limite dell'array significherebbe che Chrome convertirà l'array nel suo formato più lento (con una penalità temporale aggiuntiva per il processo di de-op effettivo). Questo è secondo i discorsi degli ultimi 12 mesi (come Google I/O), e dato per cambiare/migliorare, ovviamente. – Norguard

+1

@Norguard Non capisco come questo risponda alla domanda di OP. Non spiega la variazione del risultato tra chrome e firefox. La domanda riguarda il modo in cui vengono eseguite le ottimizzazioni degli array su entrambi e come/perché vengono eseguiti in modo diverso. (Inoltre, guarda il jsperf che ha incluso, cioè il caso di test) –

Problemi correlati