如何测量函数执行所花费的时间

IT技术 javascript profiling
2021-01-24 06:55:57

我需要以毫秒为单位获得执行时间。

我最初在 2008 年问过这个问题。当时接受的答案是使用new Date().getTime()但是,我们现在都同意使用标准performance.now()API 更合适。因此,我正在更改对此的公认答案。

6个回答

使用 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它需要导入performance

导入性能

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() 文件:

是的,您可以执行 `totalTime += console.timeEnd('timer')' 并为每个计时器执行此操作
2021-03-19 06:55:57
这是目前从我的理解中收集准确时间的最佳方式。
2021-03-20 06:55:57
不需要在这两个语句之间执行函数吗?您现在测量定义它所需的时间,而不是执行它。如我错了请纠正我...
2021-04-01 06:55:57
Chrome 开发者工具现在也支持它。
2021-04-04 06:55:57
链接到有关此功能的 MDN 文章:developer.mozilla.org/en-US/docs/DOM/console.time
2021-04-06 06:55:57

使用new Date().getTime()

getTime() 方法返回自 1970 年 1 月 1 日午夜以来的毫秒数。

前任。

var start = new Date().getTime();

for (i = 0; i < 50000; ++i) {
// do something
}

var end = new Date().getTime();
var time = end - start;
alert('Execution time: ' + time);
时间不准确,因为 Date 不适用于此功能。我将在这里大胆地说,如果你想要准确的时间,你应该使用 vsync 的例子。虽然它只适用于 Chrome 和 Firefox ATM。
2021-03-22 06:55:57
@AshBlue,我们应该使用window.performance.now. 参见stackoverflow.com/a/15641427/632951
2021-04-02 06:55:57
请注意, getMilliseconds() 为您提供当前秒的毫秒分数。如果将 getTime() 替换为 getMilliseconds(),则跨一秒可能会得到负面结果。
2021-04-03 06:55:57
请注意,您可以将 +new Date() 替换为 getTime() 调用: var start = +new Date(); // 做事 alert("Execution time: "+(+new Date())-start);
2021-04-07 06:55:57
按照今天的标准,vsync 的答案要正确得多,并且使用 Date() 会导致显示非常错误的结果,尤其是在 Windows 平台上,结果可能会四舍五入 + 取整到最近的 15ms 边界,从而导致奇怪的东西,例如微小代码位上的 0ms 计时。
2021-04-08 06:55:57

不要使用日期()。参见下文。

使用performance.now()

<script>
var a = performance.now();
alert('do something...');
var b = performance.now();
alert('It took ' + (b - a) + ' ms.');
</script>

它适用于:

  • IE 10++

  • 火狐 15++

  • 铬 24++

  • 野生动物园 8++

  • 歌剧 15++

  • 安卓 4.4++

  • 等等等等

console.time可能对你可行,但它是非标准的§

此功能是非标准的,不在标准轨道上。不要在面向 Web 的生产站点上使用它:它不适用于每个用户。实现之间可能存在很大的不兼容性,未来可能会改变行为。

除了浏览器支持外,performance.now似乎还有可能提供更准确的计时,因为它似乎是console.time.


<咆哮>此外,永远不要使用Date什么,因为它受到在“系统时间”的变化。这意味着当用户没有准确的系统时间时,我们得到无效的结果——比如“负时间”:

2014 年 10 月,我的系统时钟失控了,猜猜发生了什么……我打开 Gmail 并看到我当天所有的电子邮件“ 0 分钟前发送”。我还以为 Gmail 应该是由 Google 的世界级工程师构建的......

(将您的系统时钟设置为一年前并转到 Gmail,以便我们都能开怀大笑。也许有一天我们会为 JS举办一个耻辱堂Date。)

谷歌电子表格的now()功能也存在这个问题。

您唯一要使用的时间Date是您想向用户显示他的系统时钟时间。不是当你想要得到时间或测量任何东西。

不适用于我最大的挂断,即 IE7(企业客户)。我不关心在 chrome 中测量性能,它总是闪电般快速。
2021-03-14 06:55:57
我使用 Firebug Profile 和 performance.now(),它们都运行良好。Performance.now() 确认了我从 Profile 中得到的结果。
2021-03-19 06:55:57
正是我要找的!我希望能够将多次加在一起,但在控制台时间中无法真正做到这一点。
2021-03-25 06:55:57
请注意,Safari 尚不支持此功能:developer.mozilla.org/en-US/docs/Web/API/Performance.now()
2021-03-28 06:55:57
这是一种比 console.time() 更好的方法。
2021-04-01 06:55:57

如果您需要在本地开发机器上获取函数执行时间,您可以使用浏览器的分析工具或控制台命令,例如console.time()console.timeEnd()

所有现代浏览器都内置了 JavaScript 分析器。这些分析器应该提供最准确的测量,因为您不必修改现有代码,这可能会影响函数的执行时间。

要分析您的 JavaScript:

  • Chrome 中,按F12并选择Profiles选项卡,然后选择Collect JavaScript CPU Profile
  • Firefox 中,安装/打开 Firebug,然后单击Profile按钮。
  • IE 9+ 中,按F12,单击ScriptProfiler(取决于您的 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()在两个重要方面now()优于传统Date.getTime()

  1. now()是具有亚毫秒分辨率的双精度值,表示自页面导航开始以来的毫秒数。它以小数形式返回微秒数(例如,1000.123 的值是 1 秒和 123 微秒)。

  2. now()是单调递增的。这很重要,因为Date.getTime()可能在后续调用中向前甚至向后跳转。值得注意的是,如果操作系统的系统时间更新(例如原子钟同步),Date.getTime()也会更新。 now()保证总是单调递增,所以它不受操作系统系统时间的影响——它总是挂钟时间(假设你的挂钟不是原子的......)。

now()几乎可以在任何地方使用new Date().getTime()+ new Date和TDate.now()是。例外是Datenow()时间不混合,因为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 stable、Firefox 15+ 和 IE10。还有几种可用的polyfill

在野外测量执行时间的另一种选择是UserTimingUserTiming 的行为与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可用(我写的)。

优秀和最新的答案恕我直言:) 稍微编辑一下会更好。我想说的是用户时间不是“一个其他选项”进行测量,但当标杆不开发机器本身上完成较好的选择。使用 polyfill,它适用于所有浏览器。而躲着走的细节和样板performance.now,并Date为它存在的理由。
2021-03-29 06:55:57

要获得精确的值,您应该使用Performance interface现代版本的 Firefox、Chrome、Opera 和 IE 都支持它。这是一个如何使用它的示例:

var performance = window.performance;
var t0 = performance.now();
doWork();
var t1 = performance.now();
console.log("Call to doWork took " + (t1 - t0) + " milliseconds.")

Date.getTime()或者console.time()不适合测量精确的执行时间。如果快速粗略估计适合您,您可以使用它们。粗略估计,我的意思是您可以获得 15-60 毫秒的实时偏移。

查看这篇关于在 JavaScript 中测量执行时间的精彩文章作者还给出了几个关于 JavaScript 时间准确性的链接,值得一读。