Come misurare il tempo impiegato da una funzione per eseguire


1192

Devo ottenere tempi di esecuzione in millisecondi.

Inizialmente avevo posto questa domanda nel 2008. La risposta accettata era quindi quella di utilizzare il nuovo Date (). GetTime () Tuttavia, ora possiamo essere tutti d'accordo sul fatto che l'utilizzo dell'API performance.now () standard sia più appropriato. Sto quindi cambiando la risposta accettata a questa.


3
Spesso un'affermazione su ciò che si sta tentando di ottenere con i tempi di esecuzione può rivelarsi molto più utile che rispondere alla sola domanda. Oggigiorno, utilizzare gli strumenti di profilazione in Firebug o Chrome Dev è spesso un modo molto migliore per trovare il codice che sta succhiando il tuo succo di CPU.
Oligofren,

ecco come puoi farlo nel Datemodo classico , che ti dà msed è sufficiente per la maggior parte dei casi penso che albertech.blogspot.com/2015/07/… ... ma sì, dovresti davvero guardarePerformance.now
jar

5
performance.now()non funziona in Nodo. new Date().getTime()funzionerà in Nodo.
Ryan Walker,

1
numero 1000 voti positivi woop woop: D
Kiksen,

1
@oligofren - A volte potresti voler acquisire questi dati. Ho una situazione in cui sto scrivendo questo su indexedDB
ThomasRones l'

Risposte:


1757

Utilizzando performance.now () :

var t0 = performance.now()

doSomething()   // <---- The function you're measuring time for 

var t1 = performance.now()
console.log("Call to doSomething took " + (t1 - t0) + " milliseconds.")

NodeJs: è necessario importare laperformance classe


Utilizzando console.time :(Non standard)( tenore di vita )

console.time('someFunction')

someFunction() // Whatever is timed goes between the two "console.time"

console.timeEnd('someFunction')

Nota :
la stringa che viene passata aimetoditime()etimeEnd()deve corrispondere
(affinché il timer termini come previsto).

console.time() documentazioni:

  1. Documentazione di NodeJS riguardante
  2. Documentazione MDN (lato client)

27
Ora è supportato anche dagli Strumenti per sviluppatori di Chrome.
julien_c,

3
Questo è attualmente il modo migliore per raccogliere tempi precisi da quello che ho capito.
Ash Blue,

6
Non è necessario eseguire la funzione tra queste due istruzioni? Ora misuri il tempo necessario per definirlo, non per eseguirlo. Correggimi se sbaglio ...
Cristian,

2
Link all'articolo MDN su questa funzione: developer.mozilla.org/en-US/docs/DOM/console.time
nullability

6
sì, puoi fare `totalTime + = console.timeEnd ('timer') 'e farlo per ogni timer
vsync

637

usa new Date (). getTime ()

Il metodo getTime () restituisce il numero di millisecondi dalla mezzanotte del 1 gennaio 1970.

ex.

var start = new Date().getTime();

for (i = 0; i < 50000; ++i) {
// do something
}

var end = new Date().getTime();
var time = end - start;
alert('Execution time: ' + time);

9
Nota che puoi sostituire + new Date () per la chiamata getTime (): var start = + new Date (); // allerta roba ("Tempo di esecuzione:" + (+ nuova data ()) - inizio);
J c

55
I tempi non sono precisi perché la data non è prevista per questa funzionalità. Qui sarò audace e dirò che dovresti usare l'esempio di vsync se vuoi un tempismo accurato. Anche se funziona solo su Chrome e Firefox ATM.
Ash Blue,

9
Attenzione, getMilliseconds () ti dà la frazione di millisecondi del secondo corrente. Se sostituisci getTime () con getMilliseconds () puoi ottenere risultati negativi attraversando un secondo.
Ricky,

6
La risposta di vsync è molto più corretta per gli standard odierni e l'utilizzo di Date () può comportare la visualizzazione di risultati molto errati, specialmente sulla piattaforma Windows in cui i risultati possono essere arrotondati + pavimentati al limite di 15 ms più vicino, risultando in cose strane come Tempi di 0ms su piccoli bit di codice.
Oligofren,

29
@AshBlue, dovremmo usare window.performance.now. Vedere stackoverflow.com/a/15641427/632951
Pacerier

405

Non usare Date (). Leggere sotto.

Utilizzareperformance.now() :

<script>
var a = performance.now();
alert('do something...');
var b = performance.now();
alert('It took ' + (b - a) + ' ms.');
</script>

Funziona su:

  • IE 10 ++

  • FireFox 15 ++

  • Chrome 24 ++

  • Safari 8 ++

  • Opera 15 ++

  • Android 4.4 ++

  • ecc. ecc

console.timepuò essere praticabile per te , ma non è standard § :

Questa funzione non è standard e non è su una traccia standard. Non utilizzarlo su siti di produzione rivolti al Web: non funzionerà per tutti gli utenti. Ci possono essere anche grandi incompatibilità tra le implementazioni e il comportamento può cambiare in futuro.

Oltre al supporto del browser, performance.nowsembra avere il potenziale per fornire tempistiche più accurate in quanto sembra essere la versione bare-bones di console.time.


<rant> Inoltre, NON utilizzare MAI Dateper nulla perché è influenzato da cambiamenti nel "Tempo di sistema". Il che significa che sarà ottenere risultati non validi -come "timing negativo" - quando l'utente non dispone di un tempo del sistema esatto:

Nell'ottobre 2014, il mio orologio di sistema è andato in tilt e indovina un po ' ... Ho aperto Gmail e ho visto tutte le e-mail della mia giornata "inviate 0 minuti fa ". E pensavo che Gmail doveva essere costruito da ingegneri di livello mondiale da Google .......

(Imposta l'orologio di sistema su un anno fa e vai su Gmail in modo che tutti possiamo ridere. Forse un giorno avremo una Hall of Shame per JS Date.)

Anche la now()funzione di foglio di calcolo di Google soffre di questo problema.

L'unica volta che verrà utilizzata Dateè quando si desidera mostrare all'utente l' ora dell'orologio di sistema. Non quando vuoi avere il tempo o misurare qualcosa.


3
Proprio quello che stavo cercando! Voglio essere in grado di aggiungere più volte insieme, non posso davvero farlo con i tempi della console.
Ray,

8
nota che questo non è ancora supportato in Safari: developer.mozilla.org/en-US/docs/Web/API/Performance.now ()
Akos K

2
Uso Firebug Profile e performance.now (), ed entrambi funzionano bene. Performance.now () conferma il mio risultato dal profilo.
Vincent Jia,

2
Non funziona nel mio più grande hangup, che è IE7 (clienti aziendali). Non mi interessa misurare le prestazioni in Chrome, è sempre velocissimo.
Nick

2
Questo è un modo migliore di console.time ().
Sanjeev,

52

Se è necessario ottenere tempi di esecuzione delle funzioni sulla macchina di sviluppo locale , è possibile utilizzare gli strumenti di profilatura del browser o comandi della console come console.time()e console.timeEnd().

Tutti i browser moderni hanno profilatori JavaScript integrati. Questi profilatori dovrebbero fornire la misurazione più accurata in quanto non è necessario modificare il codice esistente, il che potrebbe influire sul tempo di esecuzione della funzione.

Per profilare il tuo JavaScript:

  • In Chrome , premi F12 e seleziona la scheda Profili , quindi Raccogli profilo CPU JavaScript .
  • In Firefox , installa / apri Firebug e fai clic sul pulsante Profilo .
  • In IE 9+ , premi F12 , fai clic su Script o Profiler (a seconda della versione di IE).

In alternativa, sulla tua macchina di sviluppo , puoi aggiungere strumenti al tuo codice con console.time()e console.timeEnd(). Queste funzioni, supportate in Firefox11 +, Chrome2 + e IE11 +, riportano sui timer con cui si avvia / si interrompe console.time(). time()accetta come argomento un nome timer definito dall'utente, timeEnd()quindi riporta il tempo di esecuzione dall'inizio del timer:

function a() {
  console.time("mytimer");
  ... do stuff ...
  var dur = console.timeEnd("myTimer"); // NOTE: dur only works in FF
}

Nota che solo Firefox restituisce il tempo trascorso nella timeEnd()chiamata. Gli altri browser riportano semplicemente il risultato alla console dello sviluppatore: il valore restituito di timeEnd()non è definito.

Se vuoi ottenere il tempo di esecuzione della funzione in natura , dovrai strumentare il tuo codice. Hai un paio di opzioni. Puoi semplicemente salvare l'ora di inizio e di fine eseguendo una query new Date().getTime():

function a() {
  var start = new Date().getTime();
  ... do stuff ...
  var end = new Date().getTime();
  var dur = end - start;
}

Tuttavia, l' Dateoggetto ha solo una risoluzione di millisecondi e sarà influenzato da eventuali modifiche all'orologio del sistema operativo. Nei browser moderni, c'è un'opzione migliore.

L'opzione migliore è utilizzare il tempo ad alta risoluzione , ovvero window.performance.now(). now()è meglio del tradizionale Date.getTime()in due modi importanti:

  1. now()è un doppio con risoluzione submillisecondo che rappresenta il numero di millisecondi dall'inizio della navigazione della pagina. Restituisce il numero di microsecondi in frazionario (ad es. Un valore di 1000.123 è 1 secondo e 123 microsecondi).

  2. now()sta aumentando monotonicamente. Questo è importante in quanto Date.getTime()può eventualmente saltare in avanti o addirittura indietro nelle chiamate successive. In particolare, se viene aggiornato l'orario di sistema del sistema operativo (ad es. Sincronizzazione dell'orologio atomico), Date.getTime()viene aggiornato. now()è garantito per essere sempre crescente monotonicamente, quindi non è influenzato dall'ora di sistema del sistema operativo - sarà sempre l'ora dell'orologio da parete (supponendo che l'orologio da parete non sia atomico ...).

now()può essere utilizzato in quasi tutti i luoghi che new Date().getTime(), e + new Datelo Date.now()sono. L'eccezione è che Datee now()volte non si mescolano, come Dateè basato su unix-epoca (il numero di millisecondi dal 1970), mentre now()è il numero di millisecondi dal momento che la navigazione pagina iniziata (quindi sarà molto più piccola di Date).

Ecco un esempio di come usare now():

function a() {
  var start = window.performance.now();
   ... do stuff ...
  var end = window.performance.now();
  var dur = end - start;
}

now()è supportato in Chrome stable, Firefox 15+ e IE10. Ci sono anche diversi polyfill disponibili.

Un'altra opzione per misurare i tempi di esecuzione in natura è UserTiming . UserTiming si comporta in modo simile a console.time()e console.timeEnd(), ma utilizza lo stesso timestamp ad alta risoluzione che now()utilizza (in modo da ottenere un clock monotonicamente crescente di un millesimo di secondo) e salva i timestamp e le durate su PerformanceTimeline .

UserTiming ha i concetti di segni (timestamp) e misure (durate). Puoi definire quanti ne desideri e sono esposti su PerformanceTimeline .

Per salvare un timestamp, si chiama mark(startMarkName). Per ottenere la durata dal primo segno, è sufficiente chiamare measure(measurename, startMarkname). La durata viene quindi salvata in PerformanceTimeline accanto ai tuoi voti.

function a() {
  window.performance.mark("start");
  ... do stuff ...
  window.performance.measure("myfunctionduration", "start");
}

// duration is window.performance.getEntriesByName("myfunctionduration", "measure")[0];

UserTiming è disponibile in IE10 + e Chrome25 +. C'è anche un polyfill disponibile (che ho scritto).


1
Risposta eccellente e più attuale IMHO :) Sarebbe ancora meglio con un po 'di editing. Direi che il timing dell'utente non è "un'altra opzione" per la misurazione, ma l' opzione preferita quando il benchmarking non viene eseguito sulla macchina di sviluppo stessa. Con il tuo polyfill funziona su tutti i browser. E nascondere i dettagli e la caldaia di performance.nowed Dateè il motivo per cui esiste.
Scambio hash

34

Per ottenere valori precisi è necessario utilizzare l' interfaccia Performance . È supportato nelle versioni moderne di Firefox, Chrome, Opera e IE. Ecco un esempio di come può essere utilizzato:

var performance = window.performance;
var t0 = performance.now();
doWork();
var t1 = performance.now();
console.log("Call to doWork took " + (t1 - t0) + " milliseconds.")

Date.getTime()o console.time()non sono utili per misurare tempi di esecuzione precisi. Puoi usarli se una stima approssimativa rapida è adatta a te. Per stima approssimativa intendo che è possibile ottenere uno spostamento di 15-60 ms dal tempo reale.

Dai un'occhiata a questo brillante post sulla misurazione dei tempi di esecuzione in JavaScript. L'autore fornisce anche un paio di collegamenti sull'accuratezza del tempo JavaScript, che vale la pena leggere.


Ottima risposta! Questo mi ha aiutato molto!
Combina il

18

Usa Firebug, abilita sia Console che Javascript. Fai clic su Profilo. Ricaricare. Fai di nuovo clic su Profilo. Visualizza il rapporto


8
Un buon consiglio ma ovviamente funziona solo per FF. Vogliamo spesso confrontare le velocità del browser ... :-)
PhiLho,

3
Nel nuovo Firebuq nascondono queste opzioni nel menu, usano CTRL + MAIUSC + P o console.profile (); console..profileEnd ()
user956584

4
Chrome supporta console.time()e console.timeEnd()anche adesso.
julien_c,

12
var StopWatch = function (performance) {
    this.startTime = 0;
    this.stopTime = 0;
    this.running = false;
    this.performance = performance === false ? false : !!window.performance;
};

StopWatch.prototype.currentTime = function () {
    return this.performance ? window.performance.now() : new Date().getTime();
};

StopWatch.prototype.start = function () {
    this.startTime = this.currentTime();
    this.running = true;
};

StopWatch.prototype.stop = function () {
    this.stopTime = this.currentTime();
    this.running = false;
};

StopWatch.prototype.getElapsedMilliseconds = function () {
    if (this.running) {
        this.stopTime = this.currentTime();
    }

    return this.stopTime - this.startTime;
};

StopWatch.prototype.getElapsedSeconds = function () {
    return this.getElapsedMilliseconds() / 1000;
};

StopWatch.prototype.printElapsed = function (name) {
    var currentName = name || 'Elapsed:';

    console.log(currentName, '[' + this.getElapsedMilliseconds() + 'ms]', '[' + this.getElapsedSeconds() + 's]');
};

Prova delle prestazioni

var stopwatch = new StopWatch();
stopwatch.start();

for (var index = 0; index < 100; index++) {
    stopwatch.printElapsed('Instance[' + index + ']');
}

stopwatch.stop();

stopwatch.printElapsed();

Produzione

Instance[0] [0ms] [0s]
Instance[1] [2.999999967869371ms] [0.002999999967869371s]
Instance[2] [2.999999967869371ms] [0.002999999967869371s]
/* ... */
Instance[99] [10.999999998603016ms] [0.010999999998603016s]
Elapsed: [10.999999998603016ms] [0.010999999998603016s]

performance.now () è facoltativo - basta passare false nella funzione di costruzione StopWatch.


12

process.hrtime () è disponibile in Node.js - restituisce un valore in nanosecondi

var hrTime = process.hrtime()
console.log(hrTime[0] * 1000000 + hrTime[1] / 1000)

1
se invece lo converti in ms e-3 anziché nel microsecondo suggerito e-6: hrtime[0] * 1000 + hrtime[1] / 1000000-> sì, preferisco usare var hrtimeanche io ! : P
cregox,

11

puoi usare aggiungi operatore anche qui

 var start = +new Date();
 callYourFunctionHere();
 var end = +new Date();
 var time = end - start;
 console.log('total execution time = '+ time + 'ms');

8

Per estendere ulteriormente il codice di vsync per avere la possibilità di restituire il timeEnd come valore in NodeJS usa questo piccolo pezzo di codice.

console.timeEndValue = function(label) { // Add console.timeEndValue, to add a return value
   var time = this._times[label];
   if (!time) {
     throw new Error('No such label: ' + label);
   }
   var duration = Date.now() - time;
   return duration;
};

Ora usa il codice in questo modo:

console.time('someFunction timer');

someFunction();

var executionTime = console.timeEndValue('someFunction timer');
console.log("The execution time is " + executionTime);


Questo ti dà più possibilità. È possibile memorizzare i tempi di esecuzione da utilizzare per più scopi come utilizzarli in equazioni o archiviati in un database, inviati a un client remoto tramite socket Web, pubblicati su una pagina Web, ecc.


8

È possibile utilizzare solo una variabile:

var timer = -performance.now();

// Do something

timer += performance.now();
console.log("Time: " + (timer/1000).toFixed(5) + " sec.")

timer/1000 - per convertire i millisecondi in secondi

.toFixed(5) - per tagliare cifre extra


5

Dato che console.timee performance.nownon sono supportati in alcuni dei principali browser (ad es. IE10), ho creato una sottile utility che utilizza i migliori metodi disponibili. Tuttavia, manca la gestione degli errori per falsi utilizzi (chiamando End()un timer non inizializzato).

Usalo e miglioralo come vuoi.

Performance: {
    Timer: {},
    Start: function (name) {
        if (console && console.time) {
            console.time(name);
        } else if (window.performance.now) {
            this.Timer[name] = window.performance.now();
        } else {
            this.Timer[name] = new Date().getTime();
        }
    },
    End: function (name) {
        if (console && console.time) {
            console.timeEnd(name);
        } else {
            var result;
            if (window.performance.now) {
                result = window.performance.now() - this.Timer[name];
            } else {
                result = new Date().getTime() - this.Timer[name];
            }
            console.log(name + ": " + result);
        }
    }
}

5

Potrebbe esserti d'aiuto.

var t0 = date.now(); doSomething(); var t1 = date.now(); console.log("Call to doSomething took approximate" + (t1 - t0)/1000 + " seconds.")


1
Sebbene questo frammento di codice possa risolvere la domanda, inclusa una spiegazione aiuta davvero a migliorare la qualità del tuo post. Ricorda che in futuro stai rispondendo alla domanda dei lettori e che queste persone potrebbero non conoscere i motivi del tuo suggerimento sul codice. Cerca anche di non aggiungere il tuo codice a commenti esplicativi, ciò riduce la leggibilità sia del codice che delle spiegazioni!
Filnor,

5

Ecco un decoratore per le funzioni di temporizzazione

let timed = (f) => (...args)=>{
    let start = performance.now();
    let ret = f(...args);
    console.log(`function ${f.name} took ${(performance.now()-start).toFixed(3)}ms`)
    return ret;   
}

Uso:

let test = ()=>{/*does something*/}
test = timed(test)   // turns the function into a timed function in one line
test()               // run your code as normal, logs 'function test took 1001.900ms' 

Se stai usando le funzioni asincrone puoi creare timedasincrono e aggiungere un carattere awaitprima di f (... args), e questo dovrebbe funzionare per quelli. Diventa più complicato se vuoi che un decoratore gestisca sia le funzioni di sincronizzazione che quelle asincrone.


Questo e 'esattamente quello che stavo cercando. Grazie!
Andrew Watters,

C'è un modo per renderlo universale anche con le funzioni asincrone?
TotalAMD

4

Grazie, Achim Koellner, espanderà un po 'la tua risposta:

var t0 = process.hrtime();
//Start of code to measure

//End of code
var timeInMilliseconds = process.hrtime(t0)[1]/1000000; // dividing by 1000000 gives milliseconds from nanoseconds

Si noti che non si dovrebbe fare nulla a parte ciò che si desidera misurare (ad esempio, console.logci vorrà del tempo anche per l'esecuzione e influenzerà i test delle prestazioni).

Si noti che per misurare il tempo di esecuzione delle funzioni asincrone, è necessario inserire var timeInMilliseconds = process.hrtime(t0)[1]/1000000;all'interno del callback. Per esempio,

var t0 = process.hrtime();
someAsyncFunction(function(err, results) {
var timeInMilliseconds = process.hrtime(t0)[1]/1000000;

});

3

Un paio di mesi fa ho messo insieme la mia routine che a volte una funzione usando Date.now () - anche se al momento il metodo accettato sembrava essere performance.now () - perché l'oggetto performance non è ancora disponibile (costruito -in) nella versione stabile di Node.js.

Oggi stavo facendo qualche ricerca in più e ho trovato un altro metodo per il cronometraggio. Dato che ho anche scoperto come usarlo nel codice Node.js, ho pensato di condividerlo qui.

Il seguente è combinato dagli esempi forniti da w3c e Node.js :

function functionTimer() {
    performance.mark('start')
    functionToBeTimed()
    performance.mark('end')
    performance.measure('Start to End', 'start', 'end')
    const measure = performance.getEntriesByName('Start to End')[0]
    console.log(measure.duration)
}

NOTA:

Se si intende utilizzare l' performanceoggetto in un'app Node.js, è necessario includere i seguenti requisiti: const { performance } = require('perf_hooks')


Penso che non sia necessario performance.mark('end')in questo caso
Kofifus,

3

ci sono molti modi per raggiungere questo obiettivo:

  1. utilizzando console.time

    console.time('function');
    //run the function in between these two lines for that you need to 
    //measure time taken by the function. ("ex. function();")
    console.timeEnd('function');
  2. questo è il modo più efficiente: usare performance.now () , ad es

    var v1 = performance.now();
    //run the function here for which you have top measure the time 
    var v2 = performance.now();
    console.log("total time  taken = "+(v2-v1)+"milliseconds");
  3. usa + (aggiungi operatore) o getTime ()

    var h2 = +new Date(); //or
    var h2 = new Date().getTime();
    for(i=0;i<500;i++) { /* do something */}
    var h3 = +new Date();   //or 
    var h3 = new Date().getTime();
    var timeTaken = h3-h2;
    console.log("time ====", timeTaken);

Ecco cosa succede quando si applica l'operatore più unario a un'istanza Date: ottenere il valore dell'istanza Date in questione Convertirlo in un numero

NOTA: getTime()offre prestazioni migliori rispetto all'operatore unario +.


1
export default class Singleton {

  static myInstance: Singleton = null;

  _timers: any = {};

  /**
   * @returns {Singleton}
   */
  static getInstance() {
    if (Singleton.myInstance == null) {
      Singleton.myInstance = new Singleton();
    }

    return this.myInstance;
  }

  initTime(label: string) {
    this._timers[label] = Date.now();
    return this._timers[label];
  }

  endTime(label: string) {
    const endTime = Date.now();
    if (this._timers[label]) {
      const delta = endTime - this._timers[label];
      const finalTime = `${label}: ${delta}ms`;
      delete this._timers[label];
      return finalTime;
    } else {
      return null;
    }
  }
}

InitTime relativo a string.

return Singleton.getInstance().initTime(label); // Returns the time init

return Singleton.getInstance().endTime(label); // Returns the total time between init and end


1

Se vuoi misurare il tempo tra più cose che non sono nidificate puoi usare questo:

function timer(lap){ 
    if(lap) console.log(`${lap} in: ${(performance.now()-timer.prev).toFixed(3)}ms`); 
    timer.prev = performance.now();
}

Simile a console.time (), ma utilizzo più semplice se non è necessario tenere traccia dei timer precedenti.

Se ti piace il colore blu da console.time (), puoi invece usare questa linea

console.log(`${lap} in: %c${(performance.now()-timer.prev).toFixed(3)}ms`, 'color:blue');

// Usage: 
timer()              // set the start
// do something 
timer('built')       // logs 'built in: 591.815ms'
// do something
timer('copied')      // logs 'copied in: 0.065ms'
// do something
timer('compared')    // logs 'compared in: 36.41ms'

1

Nel mio caso, preferisco usare @ grammar suger e compilarlo con babel.
Il problema di questo metodo è che la funzione deve essere all'interno dell'oggetto.

Codice JS di esempio

function timer() {
    return (target, propertyKey, descriptor) => {
        const start = Date.now();
        let oldFunc = descriptor.value;

        descriptor.value = async function (){
            var result = await oldFunc.apply(this, arguments);
            console.log(Date.now() - start);
            return result;
        }
    }
}

// Util function 
function delay(timeout) {
    return new Promise((resolve) => setTimeout(() => {
        resolve();
    }, timeout));
}

class Test {
    @timer()
    async test(timout) {
        await delay(timout)
        console.log("delay 1");
        await delay(timout)
        console.log("delay 2");
    }
}

const t = new Test();
t.test(1000)
t.test(100)

.babelrc (per babel 6)

 {
    "plugins": [
        "transform-decorators-legacy"
    ]
 }

1

Cronometro con cicli cumulativi

Funziona con server e client (Nodo o DOM), utilizza l' PerformanceAPI. Buono quando hai molti piccoli cicli, ad esempio in una funzione chiamata 1000 volte che elabora 1000 oggetti dati ma vuoi vedere come ogni operazione in questa funzione si somma al totale.

Quindi questo usa un timer globale del modulo (singleton). Come un modello singleton di classe, solo un po 'più semplice da usare, ma è necessario inserirlo in un stopwatch.jsfile separato, ad es .

const perf = typeof performance !== "undefined" ? performance : require('perf_hooks').performance;
const DIGITS = 2;

let _timers = {};

const _log = (label, delta?) => {
    if (_timers[label]) {
        console.log(`${label}: ` + (delta ? `${delta.toFixed(DIGITS)} ms last, ` : '') +
            `${_timers[label].total.toFixed(DIGITS)} ms total, ${_timers[label].cycles} cycles`);
    }
};

export const Stopwatch = {
    start(label) {
        const now = perf.now();
        if (_timers[label]) {
            if (!_timers[label].started) {
                _timers[label].started = now;
            }
        } else {
            _timers[label] = {
                started: now,
                total: 0,
                cycles: 0
            };
        }
    },
    /** Returns total elapsed milliseconds, or null if stopwatch doesn't exist. */
    stop(label, log = false) {
        const now = perf.now();
        if (_timers[label]) {
            let delta;
            if(_timers[label].started) {
                delta = now - _timers[label].started;
                _timers[label].started = null;
                _timers[label].total += delta;
                _timers[label].cycles++;
            }
            log && _log(label, delta);
            return _timers[label].total;
        } else {
            return null;
        }
    },
    /** Logs total time */
    log: _log,
    delete(label) {
        delete _timers[label];
    }
};

1

Il modo migliore sarebbe usare il performance hooksmodulo. Anche se instabile, è possibile markaree specifiche del codice e measurela durationtra le aree contrassegnate.

const { performance, PerformanceObserver } = require('perf_hooks');

const measures = []

const obs = new PerformanceObserver(list => measures.push(...list.getEntries()));
obs.observe({ entryTypes: ['measure'] });
const getEntriesByType = cb => cb(measures);

const doSomething = val => {
  performance.mark('beginning of the process');

  val *= 2;

  performance.mark('after multiplication');

  performance.measure('time taken', 'beginning of the process', 'after multiplication');

  getEntriesByType(entries => {
    entries.forEach(entry => console.log(entry));
  })

  return val;
}

doSomething(4);

Prova qui


0
const { performance } = require('perf_hooks');

function addUpTo(n) {
  let total = 0;
  for (let i = 1; i <= n; i++) {
    total += i;
  }
  return total;
}


let t1 = performance.now();
addUpTo(1000000000);
let t2 = performance.now();
console.log(`Time elapsed: ${(t2 - t1) / 1000} seconds`);
// Time elapsed: 1.1261566010713577 seconds

0

Con prestazioni

NodeJs: è necessario importare la classe di prestazione

var time0 = performance.now(); // Store the time at this point into time0

yourFunction();   // The function you're measuring time for 

var time1 = performance.now(); // Store the time at this point into time1

console.log("youFunction took " + (time1 - time0) + " milliseconds to execute");

Utilizzando console.time

console.time('someFunction');

someFunction(); // Whatever is timed goes between the two "console.time"

console.timeEnd('someFunction');

0
  1. Per avviare il timer utilizzareconsole.time("myTimer");
  2. Opzionale: per stampare il tempo trascorso, utilizzare console.timeLog("myTimer");
  3. Infine, per interrompere il timer e stampare l'ora finale:console.timeEnd("myTimer");

Si può leggere di più su questo su MDN e nella documentazione di Node.js .

Disponibile su Chrome, Firefox, Opera e NodeJS. (non su Edge o Internet Explorer).


-2

Come precedentemente indicato, controlla e usa il timer incorporato. Ma se vuoi o devi scrivere il tuo ecco i miei due centesimi:

//=-=|Source|=-=//
/**
 * JavaScript Timer Object
 *
 *      var now=timer['elapsed'](); 
 *      timer['stop']();
 *      timer['start']();
 *      timer['reset']();
 * 
 * @expose
 * @method timer
 * @return {number}
 */
timer=function(){
    var a=Date.now();
    b=0;
    return{
        /** @expose */
        elapsed:function(){return b=Date.now()-a},
        start:function(){return a=Date.now()},
        stop:function(){return Date.now()},
        reset:function(){return a=0}
    }
}();

//=-=|Google Advanced Optimized|=-=//
timer=function(){var a=Date.now();b=0;return{a:function(){return b=Date.now()-a},start:function(){return a=Date.now()},stop:function(){return Date.now()},reset:function(){return a=0}}}();

La compilazione è stata un successo!

  • Dimensione originale: 219 byte compressi con gzip (405 byte non compressi)
  • Dimensione compilata: 109 byte compressi con gzip (187 byte non compressi)
  • Risparmiato il 50,23% di sconto sulla dimensione gzip (53,83% senza gzip

-6

La risposta accettata è sbagliata !

Poiché JavaScript è asincrono, i valori dell'estremità variabile della risposta accettata sarebbero errati.

var start = new Date().getTime();

for (i = 0; i < 50000; ++i) {
// JavaScript is not waiting until the for is finished !!
}

var end = new Date().getTime();
var time = end - start;
alert('Execution time: ' + time); 

L'esecuzione del for potrebbe essere molto veloce, quindi non puoi vedere che il risultato è sbagliato. Puoi testarlo con un codice facendo una richiesta:

var start = new Date().getTime();

for (i = 0; i < 50000; ++i) {
  $.ajax({
    url: 'www.oneOfYourWebsites.com',
    success: function(){
       console.log("success");
    }
  });
}

var end = new Date().getTime();
var time = end - start;
alert('Execution time: ' + time); 

Quindi l'avviso verrà richiesto molto rapidamente ma nella console vedrai che le richieste Ajax continuano.

Ecco come dovresti farlo: https://developer.mozilla.org/en-US/docs/Web/API/Performance.now


9
Non è a causa del ciclo for. Un ciclo for attenderà fino all'ultimo loop fino a quando non andrà giù nel codice sorgente. Le chiamate AJAX sono asincrone. E ci sono anche altre funzioni che eseguono l'asincronizzazione. Ma un ciclo for non è eseguibile asincrono.
Scriptlabs,
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.