如何准确计算一段 JavaScript 代码的执行时间? console.time/timeEnd ,new Date.now(),Performance 对象这三个计算出来的时间正确吗?
发布于 6 年前 作者 tmxklzp 2931 次浏览 来自 问答

昨天发在了https://www.v2ex.com/t/477737上,但是回复比较少……

我想获取浏览器(Chrome)环境下一整段 JavaScript 代码中每一小段代码精确的执行时间,使用了三种计算方式:

1.console.time、console.timeEnd 配合使用
2.console.log(new Date().getTime())
3.console.log(performance.now())

但是这三种方式计算出来的时间都和我“观察感觉到的时间”有所差异,实际使用断点进行 debug 时也有同样的感觉。

debug 时感觉每小段代码的耗时和感觉一致:代码循环和递归多的地方耗时长,一两行的地方耗时短,使用上述三种计算方式时会出现:本应该耗时长的代码段算出来的时间短、本应该耗时很短的地方显示的时间很长的情况,甚至出现了两个连在一起的 console 计算出来的时间差了 500ms,例如:

// 前面的代码,省略
......
// 中间某段代码
console.log("calcBefore", performance.now())
// 一个有很多循环和递归计算的代码
calculate()
console.log("calcAfter1", performance.now())
console.log("calcAfter2", performance.now())
console.log("calcAfter3", performance.now())
console.log("calcAfter4", performance.now())
// 后面的代码,省略
......
// 打印结果
calcBefore 573.499999998603
calcAfter1 633.2000000038533
calcAfter2 1221.1999999999534
calcAfter3 1222.6000000009662
calcAfter4 1223.5000000000582

这个问题可以稳定复现,如果将calculate()注释掉的话时间正常,如下图:

console.log("calcBefore", performance.now())
calculate()
console.log("calcAfter1", performance.now())
console.log("calcAfter2", performance.now())

// console
calcBefore 1134.9999999947613
calcAfter1 1214.80000000156
calcAfter2 1878.7000000011176


console.log("calcBefore", performance.now())
//calculate()
console.log("calcAfter1", performance.now())
console.log("calcAfter2", performance.now())

// console
calcBefore 669.3999999988591
calcAfter1 671.6000000014901
calcAfter2 672.5000000005821

搜了一下,没有发现很多相关资料,只有知乎的一篇文章:https://zhuanlan.zhihu.com/p/28978126 描述了类似的事情。

问 jjc 大佬得到的回复:“凡是带有 gc 和 jit 的 runtime,统计都会不准确”。

希望得到更详细一点的解释,或者能指明一个技术点或知识文章让我自己去学习。 恳请大佬解惑。感谢!

2 回复

執行權給了其它process了吧? 不太確定計時器在process waiting 時會不會停止 另外可以參考測試nodejs 的process.hrtime

1,计算n次运算的平均值, 2,console.log最后输出,中间只是拿变量存值

来自酷炫的 CNodeMD

回到顶部