Qualche tempo fa avevo seguito un corso online di Javascript, recente e ben fatto, tanto per verificare che le mie conoscenze dello strumento che uso tutti i giorni fossero corrette e aggiornate. Una delle puntate riguardava le performance, e poneva particolare enfasi sull’importanza di scrivere bene i cicli per far evitare all’interprete letture inutili e ottimizzarne così le prestazioni, e con mia grande gioia ho appurato di essere allineato al “professore”. Poi però mi sono ricordato di come un mio amico molto esperto mi disse che secondo lui tutte queste considerazioni sono più dannose che inutili grazie all’efficienza degli ultimi interpreti Javascript, V8 e SpiderMonkey su tutti.
Forse qualcuno potrebbe considerare anacronistico porsi questi problemi nel 2015, specialmente parlando di un linguaggio usato generalmente ad alto livello, ma per me quando si scrive codice bisogna sempre cercare di farlo nel modo migliore, quindi ecco un semplice test.
var arr, i, sum, beginTime, iLimit; arr = new Array(100000); for (i=arr.length-1;i>0;i--){ arr[i] = i; } // first sum = 0; beginTime = +new Date(); for (i in arr){ sum += arr[i]; } console.log(new Date() - beginTime); // second sum = 0; beginTime = +new Date(); for (i=0;i<arr.length;i++){ sum += arr[i]; } console.log(new Date() - beginTime); // third sum = 0; beginTime = +new Date(); for (i=0, iLimit=arr.length;i<iLimit;i++){ sum += arr[i]; } console.log(new Date() - beginTime); // fourth sum = 0; beginTime = +new Date(); for (i=arr.length-1;i>0;i--){ sum += arr[i]; } console.log(new Date() - beginTime);
Sarei tentato di lasciarvi senza responso per farvi copiare e incollare questo codice sulle console di Chrome e Firefox, ma lungi da me essere crudele vi anticipo il verdetto (che potete immaginare leggendo il titolo dell’articolo): scriveteli come vi rimane più comodo.
Le due forme centrali, cioè il ciclo for normale “dall’inizio alla fine” e quello “dall’inizio alla fine con memorizzazione della dimensione”, sono su entrambe le console i più lenti. Ma mentre per il secondo esempio ce lo si poteva aspettare così non è per il terzo, che a detta del “professore” dovrebbe essere quanto meno più veloce del secondo, eppure così non è.
Forse non è corretto includere in questo test il for-in del primo esempio, perché ha una semantica e un utilizzo diversi rispetto agli altri, ma nonostante la sua maggior versatilità per V8 è proprio questo il vincitore, mentre per SpiderMonkey è il “ciclo for a rovescio” a vincere.
Conclusioni
In sostanza se non sapete dove sarà eseguito il vostro codice non avete elementi per stabilire quale forma è migliore, e anche se lo sapeste tutto sarebbe vanificato dal progresso dagli avanzatissimi algoritmi di calcolo messi in campo da Google e Mozilla. Quindi lasciate perdere e scrivete i vostri cicli come vi rimane più comodo, possibilmente a rovescio se il vostro algoritmo ve lo consente, ma evitando inutili complicanze come quella di salvarsi la dimensione dell’array… che io faccio sempre.