Comment mesurer le temps d'exécution du code javascript avec des rappels

j'ai un morceau de code javascript que j'exécute en utilisant le noeud.js interprète.

for(var i = 1; i < LIMIT; i++){
    db.users.save({id : i, name : "MongoUser [" + i + "]"}, function(err, saved) {
          if( err || !saved ) console.log("Error");
          else console.log("Saved");
    });
}

je veux savoir comment mesurer le temps pris par ces db opérations d'insertion. Je pourrais calculer la différence des valeurs de Date après et avant ce morceau de code, mais ce serait incorrect en raison de la nature asynchrone du code.

255
demandé sur Stormshadow 2012-05-16 14:55:35

12 réponses

utilisez le noeud.js console.time() et console.timeEnd() :

var i;
console.time("dbsave");

for(i = 1; i < LIMIT; i++){
    db.users.save({id : i, name : "MongoUser [" + i + "]"}, end);
}

end = function(err, saved) {
    console.log(( err || !saved )?"Error":"Saved");
    if(--i === 1){console.timeEnd("dbsave");}
};
577
répondu user2362662 2014-11-04 18:46:50

il existe une méthode conçue à cet effet. Vérifier le processus .hrtime (); .

donc, j'ai mis ça en haut de mon application.

var start = process.hrtime();

var elapsed_time = function(note){
    var precision = 3; // 3 decimal places
    var elapsed = process.hrtime(start)[1] / 1000000; // divide by a million to get nano to milli
    console.log(process.hrtime(start)[0] + " s, " + elapsed.toFixed(precision) + " ms - " + note); // print message + time
    start = process.hrtime(); // reset the timer
}

ensuite je l'utilise pour voir combien de temps les fonctions prennent. Voici un exemple de base qui imprime le contenu d'un fichier texte appelé "de sortie.txt":

var debug = true;
http.createServer(function(request, response) {

    if(debug) console.log("----------------------------------");
    if(debug) elapsed_time("recieved request");

    var send_html = function(err, contents) {
        if(debug) elapsed_time("start send_html()");
        response.writeHead(200, {'Content-Type': 'text/html' } );
        response.end(contents);
        if(debug) elapsed_time("end send_html()");
    }

    if(debug) elapsed_time("start readFile()");
    fs.readFile('output.txt', send_html);
    if(debug) elapsed_time("end readFile()");

}).listen(8080);

voici un test rapide que vous pouvez exécuter dans un terminal (shell BASH):

for i in {1..100}; do echo $i; curl http://localhost:8080/; done
177
répondu D.Deriso 2013-06-07 09:08:16

en invoquant console.time('label') enregistrera l'heure courante en millisecondes, puis en appelant console.timeEnd('label') affichera la durée à partir de ce point.

le temps en millisecondes sera automatiquement imprimé à côté de l'étiquette, donc vous n'aurez pas à faire un appel séparé à la console.pour imprimer une étiquette:

console.time('test');
//some code
console.timeEnd('test'); //Prints something like that-> test: 11374.004ms

pour plus d'informations, voir .

40
répondu jfcorugedo 2018-01-25 15:41:44
var start = +new Date();
var counter = 0;
for(var i = 1; i < LIMIT; i++){
    ++counter;
    db.users.save({id : i, name : "MongoUser [" + i + "]"}, function(err, saved) {
          if( err || !saved ) console.log("Error");
          else console.log("Saved");
          if (--counter === 0) 
          {
              var end = +new Date();
              console.log("all users saved in " + (end-start) + " milliseconds");
          }
    });
}
15
répondu Andrey Sidorov 2012-05-16 12:54:13

pour quiconque veut obtenir la valeur du temps écoulé au lieu de la sortie de la console:

utiliser .hrtime() @D. Deriso suggestion, ci-dessous mon approche la plus simple :

function functionWantToMeasure() {
    var startTime = process.hrtime();
    //do some task...
    var elapsedSeconds = parseHrtimeToSeconds(process.hrtime(startTime));
    console.log('functionWantToMeasure takes ' + elapsedSeconds + 'seconds');
}

function parseHrtimeToSeconds(hrtime) {
    var seconds = (hrtime[0] + (hrtime[1] / 1e9)).toFixed(3);
    return seconds;
}
11
répondu Andy Chen 2017-11-28 06:33:47

ancienne question mais pour une API simple et une solution légère; vous pouvez utiliser perfy qui utilise la haute résolution en temps réel ( process.hrtime ) à l'interne.

var perfy = require('perfy');

function end(label) {
    return function (err, saved) {
        console.log(err ? 'Error' : 'Saved'); 
        console.log( perfy.end(label).time ); // <——— result: seconds.milliseconds
    };
}

for (var i = 1; i < LIMIT; i++) {
    var label = 'db-save-' + i;
    perfy.start(label); // <——— start and mark time
    db.users.save({ id: i, name: 'MongoUser [' + i + ']' }, end(label));
}

notez que chaque fois que perfy.end(label) est appelé, cette instance est auto-détruite.

Divulgation: a Écrit ce module, inspiré par D. Deriso la réponse de . Docs ici .

8
répondu Onur Yıldırım 2017-05-23 12:34:53

surpris que personne n'a encore mentionné le nouveau construit dans les bibliothèques:

disponible dans le noeud > = 8,5, et devrait être dans les Browers modernes

https://developer.mozilla.org/en-US/docs/Web/API/Performance

https://nodejs.org/docs/latest-v8.x/api/perf_hooks.html#

const { performance } = require('perf_hooks');
const delay = time => new Promise(res=>setTimeout(res,time))
async function doSomeLongRunningProcess(){
  await delay(5000);
}
performance.mark('A');
(async ()=>{
  await doSomeLongRunningProcess();
  performance.mark('B');
  performance.measure('A to B', 'A', 'B');
  const measure = performance.getEntriesByName('A to B')[0];
  console.log(measure.duration);
  // Prints the number of milliseconds between Mark 'A' and Mark 'B'
})();

https://repl.it/repls/OptimalOvercookedBusinesses

3
répondu Cody G. 2018-07-29 22:06:53

vous pouvez donner Benchmark.js un essai. Il prend en charge de nombreuses plates-formes parmi eux également noeud.js.

2
répondu jsbeckr 2012-05-16 12:30:23

vous pouvez aussi essayer exectimer . Il vous donne des commentaires comme:

var t = require("exectimer");

var myFunction() {
   var tick = new t.tick("myFunction");
   tick.start();
   // do some processing and end this tick
   tick.stop();
}

// Display the results
console.log(t.timers.myFunction.duration()); // total duration of all ticks
console.log(t.timers.myFunction.min()); // minimal tick duration
console.log(t.timers.myFunction.max()); // maximal tick duration
console.log(t.timers.myFunction.mean()); // mean tick duration
console.log(t.timers.myFunction.median()); // median tick duration

[edit] il y a même une façon plus simple d'utiliser exectimer car il peut maintenant envelopper le code à mesurer. Votre code pourrait être enveloppé comme ceci:

var t = require('exectimer'),
Tick = t.Tick;

for(var i = 1; i < LIMIT; i++){
    Tick.wrap(function saveUsers(done) {
        db.users.save({id : i, name : "MongoUser [" + i + "]"}, function(err, saved) {
            if( err || !saved ) console.log("Error");
            else console.log("Saved");
            done();
        });
    });
}

// Display the results
console.log(t.timers.myFunction.duration()); // total duration of all ticks
console.log(t.timers.saveUsers.min()); // minimal tick duration
console.log(t.timers.saveUsers.max()); // maximal tick duration
console.log(t.timers.saveUsers.mean()); // mean tick duration
console.log(t.timers.saveUsers.median()); // median tick duration
2
répondu Alexandru Savin 2015-03-11 09:13:12

j'ai eu le même problème tout en se déplaçant d'AWS pour Azure

Pour l'express & aws, vous pouvez déjà utiliser, de temps existant() et timeEnd()

pour Azure, utilisez ceci: https://github.com/manoharreddyporeddy/my-nodejs-notes/blob/master/performance_timers_helper_nodejs_azure_aws.js

ces time() et timeEnd() utilisent la fonction hrtime() existante, qui donne une haute résolution en temps réel.

Espérons que cette aide.

1
répondu Manohar Reddy Poreddy 2017-11-07 06:03:34

je vous recommande d'essayer les NodeTime qui semble être un bon ajustement pour ce que vous essayez de faire.

0
répondu Julian Knight 2012-05-18 10:20:45

et une autre option est d'utiliser le express-debug outil:

express-debug est un outil de développement pour express. C'est un simple middleware qui injecte une sortie de débogage utile dans votre html, d'une manière non-obstructive.

il offre commodément un panneau de profilage:

temps total de traitement requis. middleware, param, et de l'itinéraire, les horaires.

aussi. pour ajouter aux réponses ci-dessus, vous pouvez cocher cette réponse pour activer n'importe quel code de profilage pour l'environnement de développement seulement.

0
répondu Wtower 2017-05-23 12:26:36