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.