情况
当编写高性能的JavaScript代码时,Chrome等标准分析工具并不总是足够的。它们似乎只提供函数级别的粒度,而且深入查找所需信息可能需要花费相当多的时间。
在.NET中,StopWatch
类为我提供了我所需的:任意代码片段的次微秒分辨率计时。
对于JavaScript,performance.now()
曾经是衡量性能的一种非常好的方法,但由于Spectre和Meltdown的出现,所有主要的浏览器都将分辨率降低到甚至不到一毫秒。
引用MDN关于performance.now()的话:
时间戳实际上并不高分辨率。为了减轻像Spectre这样的安全威胁,浏览器目前对结果进行不同程度的四舍五入。(Firefox在Firefox 59中开始四舍五入到2毫秒。)有些浏览器也可能稍微随机化时间戳。精度可能在未来版本中再次提高;浏览器开发人员仍在研究这些定时攻击以及如何最好地减轻它们。
问题
我需要微秒级的精度计时。在编写本文时,浏览器似乎没有提供任何选项或标志来禁用这些安全测量。也许我搜索的术语不正确,但我遇到的唯一文章都是关于安全问题的解释以及这些缓解措施如何解决它们。
我在这里并不关心安全方面- 我正在对自己的机器上的性能关键的JavaScript代码进行基准测试,我关心的唯一事情就是尽可能准确地测量,同时尽可能少的付出努力。
现有解决方法
有两个选择:
- 安装没有实施这些缓解措施的旧版浏览器
例如,我将不得不使用一个旧版本的FireFox进行基准测试,而使用新版本的Chrome进行浏览。那不太实际,因为我需要在所有浏览器中进行测试(最好还要在所有浏览器中进行基准测试)。此外,新的优化并未在旧版浏览器中实现,因此基准测试可能是无意义的。
- 使用WebWorkers实现自定义计时器
我看到了各种旧的博客文章,但似乎没有一篇达到我所需的高精度(毕竟以前有performance.now()
)。
问题
我如何在不使用旧版浏览器、虚拟机等方法的情况下获得一个有效的预Spectre performance.now()
?
是否有任何JavaScript编码技术或库能够实现微秒级精度?
这三种浏览器是否有任何选项或标志可以禁用这些安全措施?
我最终希望能够准确地测量不同代码片段之间的相对性能,因此,如果有一种解决方案可以给我提供ticks而不是微秒,只要它是准确的并且在各个浏览器中都可以工作,那么这也是可以接受的。
process.hrtime
。 - James Thorpe