J'ai un morceau de code javascript que j'exécute à l'aide de l'interpréteur node.js.
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 opérations d'insertion de base de données. Je pourrais calculer la différence entre les valeurs de Date après et avant ce morceau de code, mais ce serait incorrect en raison de la nature asynchrone du code.
Utilisez les Node.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");}
};
Il existe une méthode conçue pour cela. Départ process.hrtime (); .
Donc, je mets essentiellement cela au sommet 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é "output.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 (BASH Shell):
for i in {1..100}; do echo $i; curl http://localhost:8080/; done
Invoquer console.time('label')
enregistrera l'heure actuelle en millisecondes, puis l'appel ultérieur de console.timeEnd('label')
affichera la durée à partir de ce point.
Le temps en millisecondes sera automatiquement imprimé à côté de l'étiquette. Vous n'avez donc pas à appeler séparément console.log pour imprimer une étiquette:
console.time('test');
//some code
console.timeEnd('test'); //Prints something like that-> test: 11374.004ms
Pour plus d'informations, reportez-vous à la section Documents de développement de Mozilla sur console.time
.
Pour tous ceux qui souhaitent obtenir une valeur de temps écoulé au lieu d'une sortie de console:
utilisez process.hrtime () comme suggestion @ D.Deriso, voici mon approche la plus simple:
function functionToBeMeasured() {
var startTime = process.hrtime();
// do some task...
// ......
var elapsedSeconds = parseHrtimeToSeconds(process.hrtime(startTime));
console.log('It takes ' + elapsedSeconds + 'seconds');
}
function parseHrtimeToSeconds(hrtime) {
var seconds = (hrtime[0] + (hrtime[1] / 1e9)).toFixed(3);
return seconds;
}
Surpris, personne n'avait encore mentionné les nouvelles bibliothèques intégrées:
Disponible dans Node> = 8.5, et devrait l'être dans Modern Browers
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'); // enable for node
const delay = time => new Promise(res=>setTimeout(res,time))
async function doSomeLongRunningProcess(){
await delay(1000);
}
performance.mark('A');
(async ()=>{
await doSomeLongRunningProcess();
performance.mark('B');
performance.measure('A to B', 'A', 'B');
const measure = performance.getEntriesByName('A to B')[0];
// firefox appears to only show second precision.
console.log(measure.duration);
performance.clearMeasures(); // apparently you should remove entries...
// Prints the number of milliseconds between Mark 'A' and Mark 'B'
})();
https://repl.it/@CodyGeisler/NodeJsPerformanceHooks
https://nodejs.org/docs/latest-v10.x/api/perf_hooks.html
const { PerformanceObserver, performance } = require('perf_hooks');
const delay = time => new Promise(res => setTimeout(res, time))
async function doSomeLongRunningProcess() {
await delay(1000);
}
const obs = new PerformanceObserver((items) => {
console.log('PerformanceObserver A to B',items.getEntries()[0].duration);
performance.clearMarks();
});
obs.observe({ entryTypes: ['measure'] });
performance.mark('A');
(async function main(){
try{
await performance.timerify(doSomeLongRunningProcess)();
performance.mark('B');
performance.measure('A to B', 'A', 'B');
}catch(e){
console.log('main() error',e);
}
})();
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");
}
});
}
Ancienne question, mais pour une API simple et une solution légère; vous pouvez utiliser perfy qui utilise le temps réel haute résolution (process.hrtime
) en 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ée, cette instance est automatiquement détruite.
Divulgation: a écrit ce module, inspiré par réponse de D.Deriso . Docs ici .
Vous pouvez essayer Benchmark.js . Il supporte de nombreuses plates-formes parmi lesquelles également node.js.
Vous pouvez également 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 existe même un moyen plus simple d'utiliser exectimer car il peut maintenant envelopper le code à mesurer. Votre code pourrait être emballé 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
J'ai eu le même problème en passant d'AWS à Azure
Pour express & aws, vous pouvez déjà utiliser, time 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 existante hrtime (), qui donne un temps réel haute résolution.
J'espère que cela t'aides.
Et une autre option consiste à utiliser l'outil express-debug :
express-debug est un outil de développement pour express. C'est un middleware simple qui injecte une sortie de débogage utile dans votre code HTML, de manière non obstructive.
Il offre commodément un panneau de profilage:
temps total de traitement des demandes. middleware, param et timings de route.
Aussi. pour ajouter aux réponses ci-dessus, vous pouvez vérifier cette réponse pour activer tout code de profilage uniquement pour l'environnement de développement.
Je recommanderais d'essayer NodeTime , ce qui semble bien correspondre à ce que vous essayez de faire.