我需要以毫秒为单位获取执行时间。
我最初问这个问题是在2008年。当时接受的答案是使用newDate().getTime()。然而,我们现在都可以同意使用标准performance.now()API更合适。因此,我将接受的答案改为这个答案。
我需要以毫秒为单位获取执行时间。
我最初问这个问题是在2008年。当时接受的答案是使用newDate().getTime()。然而,我们现在都可以同意使用标准performance.now()API更合适。因此,我将接受的答案改为这个答案。
当前回答
如果需要在本地开发机器上获取函数执行时间,可以使用浏览器的分析工具,也可以使用console.time()和console.timeEnd()等控制台命令。
所有现代浏览器都内置JavaScript分析器。这些分析器应该提供最准确的度量,因为您不必修改现有代码,这可能会影响函数的执行时间。
要评测JavaScript:
在Chrome中,按F12并选择配置文件选项卡,然后收集JavaScript CPU配置文件。在Firefox中,安装/打开Firebug,然后单击Profile按钮。在IE 9+中,按F12,单击脚本或探查器(取决于您的IE版本)。
或者,在您的开发机器上,您可以使用console.time()和console.timeEnd()向代码中添加检测。Firefox11+、Chrome2+和IE11+支持的这些函数报告通过console.time()启动/停止的计时器。time()将用户定义的计时器名称作为参数,然后timeEnd()报告计时器启动后的执行时间:
function a() {
console.time("mytimer");
... do stuff ...
var dur = console.timeEnd("myTimer"); // NOTE: dur only works in FF
}
注意,只有Firefox在timeEnd()调用中返回经过的时间。其他浏览器只需将结果报告给开发人员控制台:timeEnd()的返回值未定义。
如果您想在野外获得函数执行时间,则必须对代码进行检测。你有两个选择。您可以通过查询new Date().getTime()来简单地保存开始和结束时间:
function a() {
var start = new Date().getTime();
... do stuff ...
var end = new Date().getTime();
var dur = end - start;
}
然而,Date对象只有毫秒分辨率,并且会受到任何操作系统系统时钟变化的影响。在现代浏览器中,有一个更好的选项。
更好的选择是使用高分辨率时间,也就是window.performance.now().nnow()在两个重要方面优于传统的Date.getTime():
now()是一个具有亚毫秒分辨率的double,表示自页面导航开始以来的毫秒数。它以小数形式返回微秒数(例如,1000.123的值为1秒和123微秒)。now()单调递增。这一点很重要,因为Date.getTime()可能会在后续调用中向前或向后跳转。值得注意的是,如果OS的系统时间被更新(例如原子时钟同步),Date.getTime()也会被更新。now()保证总是单调递增的,所以它不受操作系统系统时间的影响——它将始终是墙上的时钟时间(假设你的墙上的时钟不是原子的…)。
now()几乎可以用于newDate().getTime()、+newDate和tDate.now()所在的所有位置。例外的是Date和now()时间不混合,因为Date基于unix epoch(1970年以来的毫秒数),而now(()是页面导航开始后的毫秒数(因此它将比Date小得多)。
下面是如何使用now()的示例:
function a() {
var start = window.performance.now();
... do stuff ...
var end = window.performance.now();
var dur = end - start;
}
now()在Chrome稳定版、Firefox 15+和IE10中受支持。也有几种多边形填充可用。
在野外测量执行时间的另一个选项是UserTiming。UserTiming的行为类似于console.time()和console.timeEnd(),但它使用了now()使用的相同的高分辨率时间戳(因此您会得到一个亚毫秒单调递增的时钟),并将时间戳和持续时间保存到PerformanceTimeline。
UserTiming具有标记(时间戳)和度量(持续时间)的概念。您可以根据需要定义任意多个,并且它们将在PerformanceTimeline上显示。
要保存时间戳,请调用mark(startMarkName)。要获得自第一次标记以来的持续时间,只需调用measure(measurename,startMarkname)。然后将持续时间与标记一起保存在PerformanceTimeline中。
function a() {
window.performance.mark("start");
... do stuff ...
window.performance.measure("myfunctionduration", "start");
}
// duration is window.performance.getEntriesByName("myfunctionduration", "measure")[0];
UserTiming在IE10+和Chrome25+中可用。还有一个polyfill可用(我写的)。
其他回答
这是一个计时器功能。如果要测量未嵌套的多个对象之间的时间:
function timer(lap){
if(lap) console.log(`${lap} in: ${(performance.now()-timer.prev).toFixed(3)}ms`);
timer.prev = performance.now();
}
类似于console.time(),但如果不需要跟踪以前的计时器,则更容易使用。
用法:
timer() // set the start
// do something
timer('built') // logs 'built in: 591.815ms'
// do something
timer('copied') // logs 'copied in: 0.065ms'
// do something
timer('compared') // logs 'compared in: 36.41ms'
如果您喜欢console.time()中的蓝色,可以使用这行
console.log(`${lap} in: %c${(performance.now()-timer.prev).toFixed(3)}ms`, 'color:blue');
使用Firebug,同时启用Console和Javascript。单击配置文件。重新加载再次单击配置文件。查看报告。
使用performance.now():
var startTime = performance.now()
doSomething() // <---- measured code goes between startTime and endTime
var endTime = performance.now()
console.log(`Call to doSomething took ${endTime - startTime} milliseconds`)
在Node.js中,需要导入性能类
进口性能
const { performance } = require('perf_hooks');
使用console.time:(生活水平)
console.time('doSomething')
doSomething() // <---- The function you're measuring time for
console.timeEnd('doSomething')
注意:传递给time()和timeEnd()方法的字符串必须匹配(计时器才能按预期完成)。
console.time()文档:MDN文档Node.js文档
process.hrtime()在Node.js中可用-它返回以纳秒为单位的值
let hrTime = process.hrtime()
console.log(hrTime[0] * 1000000 + hrTime[1] / 1000)
由于console.time和performance.now在一些主要浏览器(如IE10)中不受支持,我创建了一个利用最佳可用方法的瘦实用程序。然而,它缺少错误用法的错误处理(在未初始化的计时器上调用End())。
使用它并根据您的需要进行改进。
Performance: {
Timer: {},
Start: function (name) {
if (console && console.time) {
console.time(name);
} else if (window.performance.now) {
this.Timer[name] = window.performance.now();
} else {
this.Timer[name] = new Date().getTime();
}
},
End: function (name) {
if (console && console.time) {
console.timeEnd(name);
} else {
var result;
if (window.performance.now) {
result = window.performance.now() - this.Timer[name];
} else {
result = new Date().getTime() - this.Timer[name];
}
console.log(name + ": " + result);
}
}
}