如何衡量与回调的javascript代码的执行时间(How to measure execution

2019-06-24 12:31发布

我有一块,我使用Node.js的解释执行JavaScript代码。

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

我想知道如何衡量这些数据库插入操作所花费的时间。 我可以计算日期值的差异后,这一段代码之前但这是因为代码的异步特性不正确。

Answer 1:

使用Node.js的console.time()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");}
};


Answer 2:

这里是专为这种方法。 退房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外壳)运行:

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


Answer 3:

调用console.time('label')将记录以毫秒为单位的当前时间,然后再调用console.timeEnd('label')将显示该点的持续时间。

以毫秒为单位的时间将被自动打印旁边的标签,这样你就不必进行单独的调用来CONSOLE.LOG打印标签:

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

欲了解更多信息,请参阅Mozilla的开发者文档console.time



Answer 4:

对于任何想经过时间值,而不是控制台输出:

使用process.hrtime()作为@ D.Deriso的建议,下面是我的简单的方法:

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


Answer 5:

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


Answer 6:

惊讶还没有人提到建库新:

可用在节点> = 8.5,并且应该在现代的browers

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,铬)

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

节点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);
    }
})();


Answer 7:

旧的问题,但对于一个简单的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的回答 。 文档在这里 。



Answer 8:

你可以给Benchmark.js一试。 它支持其中的许多平台也node.js中



Answer 9:

您也可以尝试exectimer 。 它可以让你喜欢的反馈:

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

[编辑]甚至有现在一个简单的方法来使用exectimer因为现在它可以包装代码来衡量。 你的代码可以包裹是这样的:

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


Answer 10:

我有同样的问题,同时从AWS移动天青

对于快递和AWS,你已经可以使用,现有的时间()和timeEnd()

对于Azure的,使用此: https://github.com/manoharreddyporeddy/my-nodejs-notes/blob/master/performance_timers_helper_nodejs_azure_aws.js

这些时间()和timeEnd()使用现有的hrtime()函数,这给高清晰度的实时性。

希望这可以帮助。



Answer 11:

我会建议您尝试NodeTime这似乎是一个非常适合你正在尝试做的。



Answer 12:

而另一种选择是使用快递调试工具:

快递调试是一个明确的开发工具。 这是简单的中间件注入有用的调试输出到HTML,在非梗阻性的方式。

它提供便利的分析面板:

总REQ处理时间。 中间件,PARAM和路由定时。

也。 添加到上面的回答,您可以检查这个答案 ,使仅用于开发环境中的任何分析代码。



文章来源: How to measure execution time of javascript code with callbacks