webentwicklung-frage-antwort-db.com.de

Wie man die Ausführungszeit von Javascript-Code mit Rückrufen misst

Ich habe einen Teil des Javascript-Codes, den ich mit dem Interpreter node.js ausführe.

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

Ich möchte wissen, wie man die Zeit misst, die von diesen DB-Einfügeoperationen benötigt wird. Ich könnte die Differenz der Datumswerte nach und vor diesem Codeteil berechnen, aber das wäre falsch, da der Code asynchron ist.

290
Stormshadow

Verwenden Sie die Node.js console.time() und 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");}
};
657
user2362662

Es gibt eine Methode, die dafür ausgelegt ist. Check out process.hrtime (); .

Also habe ich dies im Grunde ganz oben auf meine App gesetzt.

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
}

Dann benutze ich es, um zu sehen, wie lange Funktionen dauern. Hier ist ein einfaches Beispiel, das den Inhalt einer Textdatei mit dem Namen "output.txt" ausgibt:

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

Hier ist ein kurzer Test, den Sie in einem Terminal (BASH Shell) ausführen können:

for i in {1..100}; do echo $i; curl http://localhost:8080/; done
191
D.Deriso

Durch Aufrufen von console.time('label') wird die aktuelle Zeit in Millisekunden aufgezeichnet, und durch späteren Aufruf von console.timeEnd('label') wird die Dauer ab diesem Zeitpunkt angezeigt.

Die Zeit in Millisekunden wird automatisch neben dem Etikett gedruckt, sodass Sie nicht extra console.log aufrufen müssen, um ein Etikett zu drucken:

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

Weitere Informationen finden Sie unter Mozillas Entwicklerdokumente unter console.time .

62
jfcorugedo

Wenn Sie anstelle der Konsolenausgabe einen Wert für die abgelaufene Zeit erhalten möchten:

benutze process.hrtime () als @ D.Deriso Vorschlag, unten ist mein einfacherer Ansatz:

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

Überrascht hatte noch niemand die neu gebauten Bibliotheken erwähnt:

Verfügbar in Node> = 8.5 und sollte in Modern Browers sein

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

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

Knoten 8.5 ~ 9.x (Firefox, Chrome)

// 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

Knoten 10.x.

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);
    }
})();
16
Cody G
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");
          }
    });
}
16
Andrey Sidorov

Alte Frage, aber für eine einfache API und leichte Lösung; Sie können perfy verwenden, das intern hochauflösende Echtzeit (process.hrtime) verwendet.

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

Beachten Sie, dass bei jedem Aufruf von perfy.end(label) diese Instanz automatisch zerstört wird.

Disclosure: Schrieb dieses Modul, inspiriert von D.Derisos Antwort . Docs hier .

9

Sie könnten Benchmark.js ausprobieren. Es unterstützt viele Plattformen, darunter auch node.js.

2
jsbeckr

Sie könnten auch versuchen exectimer . Es gibt Ihnen Feedback wie:

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] Es gibt jetzt noch eine einfachere Möglichkeit, Exectimer zu verwenden, da es jetzt den zu messenden Code umschließen kann. Ihr Code könnte folgendermaßen verpackt sein:

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
Alexandru Savin

Ich hatte das gleiche Problem beim Wechsel von AWS zu Azure

Für express & aws können Sie bereits vorhandene time () und timeEnd () verwenden.

Verwenden Sie für Azure Folgendes: https://github.com/manoharreddyporeddy/my-nodejs-notes/blob/master/performance_timers_helper_nodejs_Azure_aws.js

Diese Funktionen time () und timeEnd () verwenden die vorhandene Funktion hrtime (), die eine hochauflösende Echtzeit liefert.

Hoffe das hilft.

Eine andere Möglichkeit ist die Verwendung des Express-Debug -Tools:

express-Debug ist ein Entwicklungswerkzeug für Express. Es handelt sich um eine einfache Middleware, die nützliche Debugging-Informationen in uneingeschränkter Weise in Ihr HTML einfügt.

Es bietet praktischerweise eine Profilierleiste:

gesamtbearbeitungszeit. Middleware-, Param- und Routen-Timings.

Ebenfalls. Um die obigen Antworten zu ergänzen, können Sie diese Antwort markieren, um Profiling-Code nur für die Entwicklungsumgebung zu aktivieren.

0
Wtower

Ich würde empfehlen, es mit NodeTime zu versuchen, was gut zu dem passt, was Sie versuchen.

0
Julian Knight