Come posso confrontare il codice JavaScript? [chiuso]


104

Esiste un pacchetto che mi aiuta a confrontare il codice JavaScript? Non mi riferisco a Firebug e strumenti simili.

Devo confrontare 2 diverse funzioni JavaScript che ho implementato. Ho molta familiarità con il modulo Benchmark ( Benchmark.pm ) di Perl e sto cercando qualcosa di simile in JavaScript.

L'enfasi sul benchmarking del codice JavaScript ha esagerato? Posso farla franca con il tempismo di una sola esecuzione delle funzioni?




So che non è a prova di proiettile e tutto, ma comunque correlato: a volte vuoi solo sapere come misurare il tempo impiegato da una funzione per essere eseguita .
Skippy le Grand Gourou

1
Un buon strumento di benchmark JavaScript che puoi trovare qui: jsben.ch
EscapeNetscape

Risposte:


36

Solo tempo diverse iterazioni di ciascuna funzione. Un'iterazione probabilmente non sarà sufficiente, ma (a seconda della complessità delle tue funzioni) da qualche parte più vicino a 100 o addirittura 1.000 iterazioni dovrebbe fare il lavoro.

Firebug ha anche un profiler se vuoi vedere quali parti della tua funzione lo stanno rallentando.

Modifica: per i futuri lettori, la risposta seguente che consiglia JSPerf dovrebbe essere la risposta corretta. Vorrei eliminare il mio, ma non posso perché è stato selezionato dall'OP. C'è molto di più nel benchmarking oltre all'esecuzione di molte iterazioni e JSPerf si occupa di questo per te.


12
La semplice temporizzazione di un numero predefinito di iterazioni del codice non è affatto a prova di proiettile . Inoltre, avere Firebug aperto disabilita il compilatore Just-In-Time (JIT) di Firefox, il che significa che i test verranno eseguiti nell'interprete, cioè molto più lentamente di quanto farebbero altrimenti. L'uso del profiler di Firebug non ti darà i risultati che ti aspetteresti.
Mathias Bynens,

1
@ Mathias: Beh, ad essere onesti, questa risposta è davvero vecchia.
Sasha Chedygov

2
Certo, senza offesa amico. Ho solo pensato di commentare per riferimento futuro ora che sono state fatte ulteriori ricerche sull'argomento.
Mathias Bynens

4
Oppure usa jsben.ch poiché jsperf è inattivo
EscapeNetscape

118

jsperf.com è il sito di riferimento per testare le prestazioni di JS. Inizia da lì. Se hai bisogno di un framework per eseguire i tuoi test dalla riga di comando o da script, usa Benchmark.js , la libreria su cui è costruito jsperf.com.

Nota: chiunque provi il codice Javascript dovrebbe informarsi sulle insidie ​​dei "microbenchmark" (piccoli test che prendono di mira una funzione o un'operazione specifica, piuttosto che test più complessi basati su modelli di codice del mondo reale). Tali test possono essere utili ma sono soggetti a imprecisioni a causa del funzionamento dei moderni runtime JS. Vale la pena guardare la presentazione di Vyacheslav Egorov sulle prestazioni e il benchmarking per avere un'idea della natura del problema.

Modifica: rimossi i riferimenti al mio lavoro JSLitmus in quanto non è più pertinente o utile.


3
Aggiornamento: usa jsperf.com: è migliorato molto e funziona molto bene per questo genere di cose. jslitmus funziona ancora, ma non è stato sviluppato attivamente da un po 'di tempo.
broofa

Questa è la risposta migliore. +1
Justin Force

1
Volevo usare jsperf, ma sembra che stia contando quante volte può eseguire il codice per un periodo di tempo, piuttosto che temporizzare la chiamata effettiva per N loop. Vorrei che avessero un'opzione da scegliere.
Jeach

1
@Jeach - jsperf fornisce "operazioni / secondo". Basta moltiplicare quel valore per il tempo (in secondi) per cui verrà eseguito il codice.
broofa

4
Aggiornamento: jsperf non è più online e non si sa quando tornerà online. Vedi questo thread GitHub per maggiori informazioni.
James Gould

74

Basta aggiungere un timer veloce al mix, che qualcuno potrebbe trovare utile:

var timer = function(name) {
    var start = new Date();
    return {
        stop: function() {
            var end  = new Date();
            var time = end.getTime() - start.getTime();
            console.log('Timer:', name, 'finished in', time, 'ms');
        }
    }
};

Idealmente dovrebbe essere inserito in una classe e non usato come globale come ho fatto per esempio sopra. Usarlo sarebbe piuttosto semplice:

var t = timer('Some label');
// code to benchmark
t.stop(); // prints the time elapsed to the js console

6
Buon uso delle chiusure qui.
Dandy

12
Per un risultato più accurato, si potrebbe voler utilizzare al performance.now()posto di Date() developer.mozilla.org/en-US/docs/Web/API/Performance/now
thormeier

Proprio quello di cui avevo bisogno - a timeIt ()
Gishu

1
Versione TypeScript: pastebin.com/gCs9CB5F
Alexander Taylor

1
Per node.js puoi usare process.hrtime () per ottenere una risoluzione in nanosecondi.
Xeoncross

56

Solo un modo semplice.

console.time('test');
console.timeEnd('test');

3
Questa dovrebbe essere la risposta accettata. L'utilizzo di un servizio di terze parti a volte non è conveniente e l'utilizzo di una semplice funzionalità incorporata è eccellente.
brainbag

1
@brainbag - La domanda riguardava il benchmarking, che implica più del semplice tempismo per quanto tempo viene eseguito un po 'di codice. Inoltre, i timer della console sono utili solo se il codice in questione impiega più di 1 millisecondo (il limite della loro risoluzione).
broofa

Potresti anche voler eseguire il tuo benchmark in una suite di test, che richiede l'accesso al valore del timer.
JamesDev

20

Ho usato questa semplice implementazione della risposta @musicfreaks. Non ci sono funzionalità, ma è davvero facile da usare. Questo bench(function(){return 1/2;}, 10000, [], this)calcolerà 1/2 10.000 volte.

/**
 * Figure out how long it takes for a method to execute.
 * 
 * @param {Function} method to test 
 * @param {number} iterations number of executions.
 * @param {Array} args to pass in. 
 * @param {T} context the context to call the method in.
 * @return {number} the time it took, in milliseconds to execute.
 */
var bench = function (method, iterations, args, context) {

    var time = 0;
    var timer = function (action) {
        var d = Date.now();
        if (time < 1 || action === 'start') {
            time = d;
            return 0;
        } else if (action === 'stop') {
            var t = d - time;
            time = 0;    
            return t;
        } else {
            return d - time;    
        }
    };

    var result = [];
    var i = 0;
    timer('start');
    while (i < iterations) {
        result.push(method.apply(context, args));
        i++;
    }

    var execTime = timer('stop');

    if ( typeof console === "object") {
        console.log("Mean execution time was: ", execTime / iterations);
        console.log("Sum execution time was: ", execTime);
        console.log("Result of the method call was:", result[0]);
    }

    return execTime;  
};



1

Se hai bisogno di qualcosa di semplice puoi fare in questo modo:

'use strict'
console.clear()

const powerOf = x => y => Math.pow(x, y)
const powerOfThree = powerOf(3)

function performanceCalc(fn, ...params) {
    const start = +new Date()
    const result = fn(...params)
    const end = +new Date()

    console.log(`Result: ${result}. Execution Time: ${end - start} ms`)
}

performanceCalc(powerOfThree, 2)

Ecco un esempio del codice


Semplice è stata sicuramente l'opzione migliore nel mio caso ... scrivere alcuni test per confrontare i tempi di risposta per le API (non c'è bisogno di tempi estremamente precisi).
kashiraja
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.