我有一段JavaScript代码,我正在使用node.js解释器执行。

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

如何测量这些数据库插入操作所花费的时间?我可以在这段代码之后和之前计算日期值的差异,但这将是不正确的,因为代码的异步性质。


当前回答

有一种方法是专门为这个设计的。签出process.hrtime();.

我基本上把这个放在应用的顶部。

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
}

然后我用它来看看函数需要多长时间。下面是一个基本的例子,打印一个名为"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);

下面是一个可以在终端(BASH shell)中运行的快速测试:

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

其他回答

老问题,但一个简单的API和轻量级的解决方案;您可以使用perfy,它在内部使用高分辨率实时(process.hrtime)。

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

注意,每次调用perfy.end(label)时,该实例都会被自动销毁。

披露:受D.Deriso的回答启发,编写了这个模块。文档。

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

令人惊讶的是,还没有人提到图书馆的新建:

在节点>= 8.5中可用,并且应该在现代浏览器中

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

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

节点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); // apparently you should clean up... performance.clearMarks(); performance.clearMeasures(); // Prints the number of milliseconds between Mark 'A' and Mark 'B' })();

https://repl.it/@CodyGeisler/NodeJsPerformanceHooks

节点12.倍

https://nodejs.org/docs/latest-v12.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);
      // apparently you should clean up...
      performance.clearMarks();
      // performance.clearMeasures(); // Not a function in Node.js 12
});
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);
    }
})();

有一种方法是专门为这个设计的。签出process.hrtime();.

我基本上把这个放在应用的顶部。

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
}

然后我用它来看看函数需要多长时间。下面是一个基本的例子,打印一个名为"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);

下面是一个可以在终端(BASH shell)中运行的快速测试:

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

我需要它是累积的,用来测量不同的东西。 构建这些函数:

function startMeasuring(key) {
  measureTimers[key] = process.hrtime();
}

function stopMeasuring(key) {
  if (!measures[key]) {
    measures[key] = 0;
  }

  let hrtime = process.hrtime(measureTimers[key]);
  measures[key] += hrtime[0] + hrtime[1] / 1e9;
  measureTimers[key] = null;
}

用法:

startMeasuring("first Promise");
startMeasuring("first and second Promises");
await new Promise((resolve) => {
  setTimeout(resolve, 1400);
});
stopMeasuring("first Promise");
stopMeasuring("first and second Promises");

startMeasuring("first and second Promises");
await new Promise((resolve) => {
  setTimeout(resolve, 600);
});
stopMeasuring("first and second Promises");

console.log("Measure Results", measures); 
/*
Measusre Results {
  setting: 0.00002375,
  'first Promise': 1.409392916,
  'first and second Promise': 2.015160376
}
*/