如何使用回调测量 JavaScript 代码的执行时间?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10617070/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I measure the execution time of JavaScript code with callbacks?
提问by Stormshadow
I have a piece of JavaScript code that I am executing using the node.js
interpreter.
我有一段 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");
}
});
}
How can I measure the time taken by these database insert operations? I could compute the difference of date values after and before this piece of code but that would be incorrect because of the asynchronous nature of the code.
如何测量这些数据库插入操作所花费的时间?我可以计算这段代码前后日期值的差异,但由于代码的异步性质,这是不正确的。
回答by user2362662
Use the Node.js console.time()
and console.timeEnd()
:
使用 Node.jsconsole.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");}
};
回答by D.Deriso
There is a method that is designed for this. Check out process.hrtime();.
有一种方法是为此而设计的。查看process.hrtime(); .
So, I basically put this at the top of my app.
所以,我基本上把它放在我的应用程序的顶部。
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
}
Then I use it to see how long functions take. Here's a basic example that prints the contents of a text file called "output.txt":
然后我用它来查看函数需要多长时间。这是一个打印名为“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);
Here's a quick test you can run in a terminal (BASH shell):
这是您可以在终端(BASH shell)中运行的快速测试:
for i in {1..100}; do echo $i; curl http://localhost:8080/; done
回答by jfcorugedo
Invoking console.time('label')
will record the current time in milliseconds, then later calling console.timeEnd('label')
will display the duration from that point.
调用console.time('label')
将以毫秒为单位记录当前时间,然后稍后调用console.timeEnd('label')
将显示从该点开始的持续时间。
The time in milliseconds will be automatically printed alongside the label, so you don't have to make a separate call to console.log to print a label:
以毫秒为单位的时间将自动打印在标签旁边,因此您不必单独调用 console.log 来打印标签:
console.time('test');
//some code
console.timeEnd('test'); //Prints something like that-> test: 11374.004ms
For more information, see Mozilla's developer docs on console.time
.
有关更多信息,请参阅Mozilla 的开发人员文档console.time
。
回答by Cody G
Surprised no one had mentioned yet the new built in libraries:
令人惊讶的是没有人提到新的内置库:
Available in Node >= 8.5, and should be in Modern Browers
在 Node >= 8.5 中可用,并且应该在现代浏览器中
https://developer.mozilla.org/en-US/docs/Web/API/Performance
https://developer.mozilla.org/en-US/docs/Web/API/Performance
https://nodejs.org/docs/latest-v8.x/api/perf_hooks.html#
https://nodejs.org/docs/latest-v8.x/api/perf_hooks.html#
Node 8.5 ~ 9.x (Firefox, Chrome)
节点 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
https://repl.it/@CodyGeisler/NodeJsPerformanceHooks
Node 10.x
节点 10.x
https://nodejs.org/docs/latest-v10.x/api/perf_hooks.html
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);
}
})();
回答by Sing
For anyone want to get time elapsed value instead of console output :
对于任何想要获取时间经过值而不是控制台输出的人:
use process.hrtime()as @D.Deriso suggestion, below is my simpler approach :
使用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;
}
回答by Andrey Sidorov
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");
}
});
}
回答by Onur Y?ld?r?m
Old question but for a simple API and light-weight solution; you can use perfywhich uses high-resolution real time (process.hrtime
) internally.
老问题,但对于简单的 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));
}
Note that each time perfy.end(label)
is called, that instance is auto-destroyed.
请注意,每次perfy.end(label)
调用时,该实例都会自动销毁。
Disclosure: Wrote this module, inspired by D.Deriso's answer. Docs here.
披露:编写此模块,灵感来自D.Deriso 的回答。文档在这里。
回答by Alexandru Savin
You could also try exectimer. It gives you feedback like:
你也可以试试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
[edit] There is even a simpler way now to use exectimer because now it can wrap the code to be measured. Your code could wrapped like this:
[编辑] 现在有一种更简单的方法来使用 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
回答by jsbeckr
You could give Benchmark.jsa try. It supports many platforms among them also node.js.
你可以试试Benchmark.js。它支持许多平台,其中还有 node.js。
回答by Manohar Reddy Poreddy
I had same issue while moving from AWS to Azure
我在从 AWS 迁移到 Azure 时遇到了同样的问题
For express & aws, you can already use, existing time() and timeEnd()
对于 express & aws,您已经可以使用现有的 time() 和 timeEnd()
For Azure, use this: https://github.com/manoharreddyporeddy/my-nodejs-notes/blob/master/performance_timers_helper_nodejs_azure_aws.js
对于 Azure,请使用:https: //github.com/manoharreddyporeddy/my-nodejs-notes/blob/master/performance_timers_helper_nodejs_azure_aws.js
These time() and timeEnd() use the existing hrtime() function, which give high-resolution real time.
这些 time() 和 timeEnd() 使用现有的 hrtime() 函数,可提供高分辨率实时。
Hope this helps.
希望这可以帮助。