461 Stimmen

Wie kann ich die Ausführungszeit von JavaScript-Code mit Rückrufen messen?

Ich habe ein Stück JavaScript-Code, den ich mit der node.js Dolmetscher.

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

Wie kann ich die Zeit messen, die diese Einfügeoperationen in die Datenbank benötigen? Ich könnte die Differenz der Datumswerte nach und vor diesem Codestück berechnen, aber das wäre wegen der asynchronen Natur des Codes nicht korrekt.

18voto

Andrey Sidorov Punkte 23966
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");
          }
    });
}

10voto

Onur Yıldırım Punkte 29717

Alte Frage, aber für eine einfache API und eine leichtgewichtige Lösung können Sie Folgendes verwenden Perfekt das mit hochauflösender Echtzeit ( process.hrtime ) intern.

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 jedes Mal, wenn perfy.end(label) aufgerufen wird, wird diese Instanz automatisch vernichtet.

Offenlegung: Ich habe dieses Modul geschrieben, inspiriert von D.Derisos Antwort . Dokumente aquí .

3voto

Alexandru Savin Punkte 636

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

[Bearbeiten] Es gibt jetzt eine noch einfachere Möglichkeit, exectime zu verwenden. Ihr Code könnte so 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

2voto

Ulad Kasach Punkte 9500

Sie können eine wrapper Funktion, um die Ausführungszeit einer beliebigen Funktion zu ermitteln.

Ein Wrapper wird verwendet, um eine bestehende Funktion zu erweitern, um etwas vor und nach der Ausführung der bestehenden Funktion zu tun - und ist ein bequemer Weg, um Logik zu komponieren.

Hier ist ein Beispiel für die Verwendung der withDurationReporting Umschlag:

// without duration reporting
const doSomethingThatMayTakeAWhile = async (someArg: string, anotherArg: number) => { 
  /** your logic goes here */
}

// with duration reporting
const doSomethingThatMayTakeAWhileWithReporting = withDurationReporting(
  'doSomethingThatMayTakeAWhile', 
  doSomethingThatMayTakeAWhile
);

// note: you can define the function with duration reporting directly, too
const doSomethingThatMayTakeAWhile = withDurationReporting(
  'doSomethingThatMayTakeAWhile', 
  async (someArg: string, anotherArg: number) => { 
    /** your logic goes here */
  }
)

Und hier ist der Wrapper selbst:

import { hrtime } from 'process';

const roundToHundredths = (num: number) => Math.round(num * 100) / 100; // https://stackoverflow.com/a/14968691/3068233

/**
 * a wrapper which reports how long it took to execute a function, after the function completes
 */
export const withDurationReporting = <R extends any, T extends (...args: any[]) => Promise<R>>(
  title: string,
  logic: T,
  options: {
    reportingThresholdSeconds: number;
    logMethod: (message: string, metadata?: Record<string, any>) => void;
  } = {
    reportingThresholdSeconds: 1, // report on anything that takes more than 1 second, by default
    logMethod: console.log, // log with `console.log` by default
  }, 
) => {
  return (async (...args: Parameters<T>): Promise<R> => {
    const startTimeInNanoseconds = hrtime.bigint();
    const result = await logic(...args);
    const endTimeInNanoseconds = hrtime.bigint();
    const durationInNanoseconds = endTimeInNanoseconds - startTimeInNanoseconds;
    const durationInSeconds = roundToHundredths(Number(durationInNanoseconds) / 1e9); // https://stackoverflow.com/a/53970656/3068233
    if (durationInSeconds >= options.reportingThresholdSeconds)
      options.logMethod(`${title} took ${durationInSeconds} seconds to execute`, { title, durationInSeconds });
    return result;
  }) as T;
};

1voto

Ich hatte dasselbe Problem beim Wechsel von AWS zu Azure

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

Für Azure verwenden Sie dies: https://github.com/manoharreddyporeddy/my-nodejs-notes/blob/master/performance_timers_helper_nodejs_azure_aws.js

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

Ich hoffe, das hilft.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X