Comment mesurer le temps mis par une fonction pour s'exécuter

1192

J'ai besoin d'obtenir le temps d'exécution en millisecondes.

J'ai initialement posé cette question en 2008. La réponse acceptée était alors d'utiliser la nouvelle Date (). GetTime () Cependant, nous pouvons tous convenir maintenant que l'utilisation de l' API standard performance.now () est plus appropriée. Je modifie donc la réponse acceptée à celle-ci.

Julius A
la source
3
Souvent, une déclaration sur ce que vous essayez d'accomplir avec le temps d'exécution peut s'avérer beaucoup plus utile que de répondre seule à la question. De nos jours, utiliser les outils de profilage dans Firebug ou Chrome Dev est souvent un bien meilleur moyen de trouver le code qui aspire votre jus de processeur.
oligofren
voici comment vous pouvez le faire de la Datemanière classique , ce qui vous donne mset est suffisant pour la majorité des cas je pense albertech.blogspot.com/2015/07/… ... mais oui, vous devriez vraiment regarderPerformance.now
pot
5
performance.now()ne fonctionne pas dans Node. new Date().getTime()fonctionnera dans Node.
Ryan Walker
1
numéro 1000 vote positif woop woop: D
Kiksen
1
@oligofren - Parfois, vous souhaiterez peut-être capturer ces données. J'ai une situation où j'écris ceci à indexedDB
ThomasRones

Réponses:

1757

Utilisation de 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: il est nécessaire d' importer laperformance classe


Utilisation de console.time :(non standard)( niveau de vie )

console.time('someFunction')

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

console.timeEnd('someFunction')

Remarque :
La chaîne transmise auxméthodestime()ettimeEnd()doit correspondre
(pour que la minuterie se termine comme prévu).

console.time() documentations:

  1. Documentation NodeJS concernant
  2. Documentation MDN (côté client)
vsync
la source
27
Il est également pris en charge par les outils de développement Chrome.
julien_c
3
C'est actuellement le meilleur moyen de collecter des horaires précis d'après ce que je comprends.
Ash Blue
6
N'avez-vous pas besoin d'exécuter la fonction entre ces deux instructions? Vous mesurez maintenant le temps qu'il faut pour le définir, pas pour l'exécuter. Corrigez-moi si je me trompe ...
Cristian
2
Lien vers l'article MDN sur cette fonctionnalité: developer.mozilla.org/en-US/docs/DOM/console.time
nullability
6
oui, vous pouvez faire `totalTime + = console.timeEnd ('timer') 'et le faire pour chaque timer
vsync
637

utilisez new Date (). getTime ()

La méthode getTime () renvoie le nombre de millisecondes depuis minuit le 1er janvier 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);
Owen
la source
9
Notez que vous pouvez substituer + new Date () à l'appel getTime (): var start = + new Date (); // alerte choses ("Heure d'exécution:" + (+ nouvelle Date ()) - début);
J c
55
Les horaires ne sont pas précis car la date n'est pas destinée à cette fonctionnalité. Je vais être audacieux ici et dire que vous devriez utiliser l'exemple de vsync si vous voulez un timing précis. Bien que cela ne fonctionne que dans Chrome et Firefox ATM.
Ash Blue
9
Attention, getMilliseconds () vous donne la fraction de millisecondes de la seconde actuelle. Si vous remplacez getTime () par getMilliseconds (), vous pouvez obtenir des résultats négatifs si vous passez une seconde.
RickyA
6
La réponse de vsync est beaucoup plus correcte par rapport aux normes d'aujourd'hui, et l'utilisation de Date () peut entraîner l'affichage de résultats très erronés, en particulier sur la plate-forme Windows où les résultats peuvent être arrondis + fondus à la limite de 15 ms la plus proche, ce qui entraîne des choses étranges telles que Timings de 0 ms sur de minuscules bits de code.
oligofren
29
@AshBlue, nous devrions utiliser window.performance.now. Voir stackoverflow.com/a/15641427/632951
Pacerier
405

N'utilisez pas Date (). Lire ci-dessous.

Utilisationperformance.now() :

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

Il fonctionne sur:

  • IE 10 ++

  • FireFox 15 ++

  • Chrome 24 ++

  • Safari 8 ++

  • Opera 15 ++

  • Android 4.4 ++

  • etc

console.timepeut être viable pour vous , mais ce n'est pas standard § :

Cette fonctionnalité n'est pas standard et n'est pas conforme aux normes. Ne l'utilisez pas sur des sites de production face au Web: cela ne fonctionnera pas pour tous les utilisateurs. Il peut également y avoir de grandes incompatibilités entre les implémentations et le comportement peut changer à l'avenir.

Outre la prise en charge du navigateur, performance.nowsemble avoir le potentiel de fournir des timings plus précis car il semble que ce soit la version simple de console.time.


<rant> Aussi, NE JAMAIS utiliser Datepour quoi que ce soit car il est affecté par les changements de "l'heure système". Ce qui signifie que nous allons obtenir des résultats invalides -comme « timing négatif » - lorsque l'utilisateur ne dispose pas d' un temps de système précis:

En octobre 2014, l'horloge de mon système s'est détraquée et devinez quoi ... J'ai ouvert Gmail et vu tous les e-mails de ma journée "envoyés il y a 0 minutes ". Et je pensais que Gmail était censé être construit par des ingénieurs de classe mondiale de Google .......

(Réglez votre horloge système sur un an et accédez à Gmail pour que nous puissions tous bien rire. Peut-être qu'un jour nous aurons un Hall of Shame pour JS Date.)

La now()fonction de Google Spreadsheet souffre également de ce problème.

La seule fois que vous utiliserez, Datec'est quand vous voulez montrer à l'utilisateur l' heure de son horloge système. Pas quand vous voulez avoir le temps ou mesurer quoi que ce soit.

Pacerier
la source
3
Exactement ce que je cherchais! Je veux pouvoir ajouter plusieurs fois ensemble, je ne peux pas vraiment faire ça avec les temps de la console.
Ray
8
notez que cela n'est pas encore pris en charge dans safari: developer.mozilla.org/en-US/docs/Web/API/Performance.now ()
Akos K
2
J'utilise Firebug Profile et performance.now (), et ils fonctionnent tous les deux bien. Performance.now () confirme mon résultat de Profile.
Vincent Jia
2
Ne fonctionne pas dans mon plus gros blocage, qui est IE7 (clients d'entreprise.) Je ne me soucie pas de mesurer les performances en chrome, c'est toujours rapide comme l'éclair.
Nick
2
C'est un meilleur moyen que console.time ().
Sanjeev
52

Si vous devez obtenir le temps d'exécution de la fonction sur votre machine de développement locale , vous pouvez utiliser les outils de profilage de votre navigateur ou des commandes de console telles que console.time()et console.timeEnd().

Tous les navigateurs modernes ont des profileurs JavaScript intégrés. Ces profileurs devraient donner la mesure la plus précise car vous n'avez pas à modifier votre code existant, ce qui pourrait affecter le temps d'exécution de la fonction.

Pour profiler votre JavaScript:

  • Dans Chrome , appuyez sur F12 et sélectionnez l' onglet Profils , puis Collecter le profil CPU JavaScript .
  • Dans Firefox , installez / ouvrez Firebug et cliquez sur le bouton Profil .
  • Dans IE 9+ , appuyez sur F12 , cliquez sur Script ou Profiler (selon votre version d'IE).

Alternativement, sur votre machine de développement , vous pouvez ajouter une instrumentation à votre code avec console.time()et console.timeEnd(). Ces fonctions, prises en charge dans Firefox11 +, Chrome2 + et IE11 +, rendent compte des minuteries via lesquelles vous démarrez / arrêtez console.time(). time()prend comme argument un nom de temporisateur défini par l'utilisateur, timeEnd()puis rend compte du temps d'exécution depuis le démarrage du temporisateur:

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

Notez que seul Firefox renvoie le temps écoulé dans l' timeEnd()appel. Les autres navigateurs signalent simplement le résultat à la console développeur: la valeur de retour de timeEnd()n'est pas définie.

Si vous souhaitez obtenir le temps d'exécution de la fonction dans la nature , vous devrez instrumenter votre code. Vous avez plusieurs options. Vous pouvez simplement enregistrer les heures de début et de fin en interrogeant new Date().getTime():

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

Cependant, l' Dateobjet n'a qu'une résolution en millisecondes et sera affecté par les modifications d'horloge système de tout système d'exploitation. Dans les navigateurs modernes, il existe une meilleure option.

La meilleure option est d'utiliser le temps de haute résolution , alias window.performance.now(). now()est meilleur que le traditionnel Date.getTime()de deux manières importantes:

  1. now()est un double avec une résolution submilliseconde qui représente le nombre de millisecondes depuis le début de la navigation de la page. Il renvoie le nombre de microsecondes dans le fractionnaire (par exemple, une valeur de 1000.123 est de 1 seconde et 123 microsecondes).

  2. now()augmente de façon monotone. Ceci est important car il Date.getTime()peut éventuellement avancer ou même reculer lors des appels suivants. Notamment, si l'heure système du système d'exploitation est mise à jour (par exemple la synchronisation de l'horloge atomique), Date.getTime()est également mise à jour. now()est garanti d'être toujours en augmentation monotone, il n'est donc pas affecté par l'heure système du système d'exploitation - ce sera toujours l'heure de l'horloge murale (en supposant que votre horloge murale n'est pas atomique ...).

now()peut être utilisé dans presque tous les endroits qui new Date().getTime(), + new Dateett Date.now()sont. L'exception est que Dateet les now()temps ne se mélangent pas, comme Datese base sur unix-époque (le nombre de millisecondes depuis 1970), alors que now()le nombre de millisecondes depuis votre page de navigation a commencé (il sera beaucoup plus petit que Date).

Voici un exemple d'utilisation now():

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

now()est pris en charge dans Chrome stable, Firefox 15+ et IE10. Il existe également plusieurs polyfills disponibles.

UserTiming est une autre option pour mesurer le temps d'exécution dans la nature . UserTiming se comporte de la même manière que console.time()et console.timeEnd(), mais il utilise le même horodatage haute résolution que celui now()utilisé (vous obtenez donc une horloge augmentant de façon monotone de moins d'une milliseconde) et enregistre les horodatages et les durées dans PerformanceTimeline .

UserTiming a les concepts de marques (horodatages) et de mesures (durées). Vous pouvez en définir autant que vous le souhaitez, et ils sont exposés sur PerformanceTimeline .

Pour enregistrer un horodatage, vous appelez mark(startMarkName). Pour obtenir la durée depuis votre première note, il vous suffit d'appeler measure(measurename, startMarkname). La durée est ensuite enregistrée dans PerformanceTimeline à côté de vos repères.

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

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

UserTiming est disponible dans IE10 + et Chrome25 +. Il existe également un polyfill disponible (que j'ai écrit).

NicJ
la source
1
Excellente et dernière réponse à mon humble avis :) Ce serait encore mieux avec un peu de retouche. Je dirais que le chronométrage utilisateur n'est pas "une autre option" pour mesurer, mais l' option préférée lorsque l'analyse comparative n'est pas effectuée sur la machine de développement elle-même. Avec votre polyfill, il fonctionne sur tous les navigateurs. Et cacher les détails et le passe-partout performance.nowet Datec'est la raison pour laquelle ils existent.
hashchange
34

Pour obtenir des valeurs précises, vous devez utiliser l' interface Performance . Il est pris en charge dans les versions modernes de Firefox, Chrome, Opera et IE. Voici un exemple de la façon dont il peut être utilisé:

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

Date.getTime()ou console.time()ne sont pas bons pour mesurer un temps d'exécution précis. Vous pouvez les utiliser si une estimation rapide et approximative vous convient. Par estimation approximative, je veux dire que vous pouvez obtenir un décalage de 15 à 60 ms par rapport au temps réel.

Vérifiez ce brillant après sur la mesure du temps d'exécution en JavaScript. L'auteur donne également quelques liens sur la précision de l'heure JavaScript, à lire.

Varvara Kalinina
la source
Très bonne réponse! Cela m'a beaucoup aidé!
Combinez le
18

Utilisez Firebug, activez la console et Javascript. Cliquez sur Profil. Recharger. Cliquez à nouveau sur Profil. Consultez le rapport.

Stefan Mai
la source
8
Bon conseil mais ne fonctionne évidemment que pour FF. Nous voulons souvent comparer les vitesses des navigateurs ... :-)
PhiLho
3
Sur le nouveau Firebuq, ils masquent ces options au menu, utilisez CTRL + MAJ + P ou console.profile (); console..profileEnd ()
user956584
4
Chrome prend en charge console.time()et console.timeEnd()aussi maintenant.
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]');
};

Référence

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

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

stopwatch.stop();

stopwatch.printElapsed();

Production

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 () est facultatif - passez simplement false dans la fonction constructeur StopWatch.

kayz1
la source
12

process.hrtime () est disponible dans Node.js - il retourne une valeur en nanosecondes

var hrTime = process.hrtime()
console.log(hrTime[0] * 1000000 + hrTime[1] / 1000)
Achim Koellner
la source
1
si vous le convertissez plutôt en ms e-3 plutôt qu'en microseconde e-6 suggéré: hrtime[0] * 1000 + hrtime[1] / 1000000-> ouais, j'utilise plutôt var hrtimeaussi! : P
cregox
11

vous pouvez également utiliser l'opérateur d'ajout ici

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

Pour étendre davantage le code de vsync pour avoir la possibilité de renvoyer le timeEnd en tant que valeur dans NodeJS, utilisez ce petit morceau de code.

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;
};

Maintenant, utilisez le code comme ceci:

console.time('someFunction timer');

someFunction();

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


Cela vous donne plus de possibilités. Vous pouvez stocker le temps d'exécution pour être utilisé à d'autres fins, comme l'utiliser dans des équations, ou stocké dans une base de données, envoyé à un client distant via des sockets Web, servi sur une page Web, etc.

Levi Roberts
la source
8

Il est possible d'utiliser une seule variable:

var timer = -performance.now();

// Do something

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

timer/1000 - pour convertir des millisecondes en secondes

.toFixed(5) - pour couper des chiffres supplémentaires

user1032559
la source
5

Depuis console.timeet performance.nowne sont pas pris en charge dans certains principaux navigateurs (ie IE10), j'ai créé un utilitaire slim qui utilise les meilleures méthodes disponibles. Cependant, il manque de gestion des erreurs pour les fausses utilisations (appel End()à un temporisateur non initialisé).

Utilisez-le et améliorez-le comme vous le souhaitez.

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);
        }
    }
}
Mx.
la source
5

Cela peut vous aider.

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

Wajeeh Aslam
la source
1
Bien que cet extrait de code puisse résoudre la question, y compris une explication aide vraiment à améliorer la qualité de votre message. N'oubliez pas que vous répondrez à la question pour les lecteurs à l'avenir, et ces personnes pourraient ne pas connaître les raisons de votre suggestion de code. Essayez également de ne pas surcharger votre code avec des commentaires explicatifs, cela réduit la lisibilité du code et des explications!
Filnor
5

Voici un décorateur pour les fonctions de synchronisation

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;   
}

Usage:

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' 

Si vous utilisez des fonctions asynchrones, vous pouvez faire de l' timedasync et ajouter un awaitavant f (... args), et cela devrait fonctionner pour celles-ci. Cela devient plus compliqué si vous voulez qu'un décorateur gère les fonctions de synchronisation et d'async.

aljgom
la source
Ceci est exactement ce que je cherchais. Je vous remercie!
Andrew Watters
Existe-t-il un moyen de le rendre universel pour l'utiliser également avec les fonctions asynchrones?
TotalAMD
4

Merci, Achim Koellner, développera un peu votre réponse:

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

Veuillez noter que vous ne devez rien faire à part ce que vous voulez mesurer (par exemple, console.log prendra également du temps à exécuter et affectera les tests de performances).

Notez que dans l'ordre par mesure du temps d'exécution des fonctions asynchrones, vous devez insérer var timeInMilliseconds = process.hrtime(t0)[1]/1000000;à l'intérieur du rappel. Par exemple,

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

});
Andrew Marin
la source
3

Il y a quelques mois, j'ai créé ma propre routine qui chronomètre une fonction en utilisant Date.now () - même si à l'époque la méthode acceptée semblait être performance.now () - parce que l'objet de performance n'est pas encore disponible (construit -in) dans la version stable de Node.js.

Aujourd'hui, je faisais plus de recherches et j'ai trouvé une autre méthode de chronométrage. Puisque j'ai également trouvé comment utiliser cela dans le code Node.js, j'ai pensé que je le partagerais ici.

Les éléments suivants sont combinés à partir des exemples donnés par w3c et 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)
}

REMARQUE:

Si vous avez l'intention d'utiliser l' performanceobjet dans une application Node.js, vous devez inclure les éléments suivants: const { performance } = require('perf_hooks')

Jonathan Chasteen
la source
Je pense que vous n'avez pas besoin performance.mark('end')dans ce cas
kofifus
3

il existe plusieurs façons d'atteindre cet objectif:

  1. en utilisant 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. c'est le moyen le plus efficace: utiliser performance.now () , par exemple

    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. utilisez + (ajouter un opérateur) ou 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);

Voici ce qui se passe lorsque vous appliquez l'opérateur unaire plus à une instance de date: Obtenez la valeur de l'instance de date en question Convertissez-la en nombre

REMARQUE: getTime()donne de meilleures performances que l'opérateur unaire +.

Rohit Jaiswal
la source
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 lié à string.

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

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

jose920405
la source
1

Si vous voulez mesurer le temps entre plusieurs choses qui ne sont pas imbriquées, vous pouvez utiliser ceci:

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

Similaire à console.time (), mais une utilisation plus facile si vous n'avez pas besoin de garder une trace des minuteries précédentes.

Si vous aimez la couleur bleue de console.time (), vous pouvez utiliser cette ligne à la place

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'
aljgom
la source
1

Dans mon cas, je préfère utiliser @ grammar suger et le compiler avec babel.
Le problème de cette méthode est que la fonction doit être à l'intérieur de l'objet.

Exemple de code JS

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 (pour babel 6)

 {
    "plugins": [
        "transform-decorators-legacy"
    ]
 }
Yu Huang
la source
1

Chronomètre avec cycles cumulatifs

Fonctionne avec serveur et client (Node ou DOM), utilise l' PerformanceAPI. Bien lorsque vous avez de nombreux petits cycles, par exemple dans une fonction appelée 1000 fois qui traite 1000 objets de données, mais que vous voulez voir comment chaque opération dans cette fonction s'ajoute au total.

Donc celui-ci utilise une minuterie globale (singleton) de module. Identique à un modèle de classe singleton, juste un peu plus simple à utiliser, mais vous devez le mettre dans un stopwatch.jsfichier eg séparé .

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];
    }
};
gombosg
la source
1

La meilleure façon serait d'utiliser le performance hooksmodule. Bien instable, vous pouvez les markzones spécifiques de votre code et measureles durationentre les zones marquées.

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);

Essayez ici

toondaey
la source
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
Homam Bahrani
la source
0

Avec performance

NodeJs: il est nécessaire d'importer la classe de performances

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");

Utilisation de console.time

console.time('someFunction');

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

console.timeEnd('someFunction');
iCPSoni
la source
0
  1. Pour démarrer la minuterie, utilisezconsole.time("myTimer");
  2. Facultatif: pour imprimer le temps écoulé, utilisez console.timeLog("myTimer");
  3. Enfin, pour arrêter le chronomètre et imprimer l'heure finale:console.timeEnd("myTimer");

Vous pouvez en savoir plus à ce sujet sur MDN et dans la documentation Node.js .

Disponible sur Chrome, Firefox, Opera et NodeJS. (pas sur Edge ou Internet Explorer).

bvdb
la source
-2

Comme indiqué précédemment, vérifiez et utilisez la minuterie intégrée. Mais si vous voulez ou devez écrire le vôtre, voici mes deux cents:

//=-=|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 compilation a été un succès!

  • Taille d'origine: 219 octets compressés (405 octets non compressés)
  • Taille compilée: 109 octets compressés (187 octets non compressés)
  • Économisez 50,23% sur la taille gzippée (53,83% sans gzip
NlaakALD
la source
-6

La réponse acceptée est fausse !

Puisque JavaScript est asynchrone, les valeurs de l'extrémité variable de la réponse acceptée seraient erronées.

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'exécution de for peut être très rapide, vous ne pouvez donc pas voir que le résultat est incorrect. Vous pouvez le tester avec un code faisant une requête:

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); 

L'alerte sera donc très rapide, mais dans la console, vous verrez que les requêtes ajax se poursuivent.

Voici comment vous devez le faire: https://developer.mozilla.org/en-US/docs/Web/API/Performance.now

Mirza Selimovic
la source
9
Ce n'est pas à cause de la boucle for. Une boucle for attendra jusqu'à la dernière boucle jusqu'à ce qu'elle continue dans votre code source. Les appels AJAX sont asynchrones. Et il existe également d'autres fonctions qui exécutent async. Mais une boucle for n'est pas un async d'exécution.
Scriptlabs