使用 javascript performance.now() 计时

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29460040/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-28 10:34:18  来源:igfitidea点击:

Timing with javascript performance.now()

javascripttiming

提问by slrom

I am trying to time the execution of my function in milliseconds. I use performance.now()in order to do that. I am able to get the time on the first run, but on the second, third, and so on runs I get 0 milliseconds. Here is an example:

我试图以毫秒为单位计时我的函数的执行时间。我使用performance.now()来做到这一点。我能够在第一次运行时获得时间,但是在第二次、第三次等运行中我得到 0 毫秒。下面是一个例子:

function someFunction (){
    var t0 = performance.now();
    //Function calculations
    var t1 = performance.now();
    Console.log(t1 - t0);
}

I launch the function onclick. It works when I first launch the page. It stops working on the second click. t0 and t1 get the same values and when I subtract them I get 0 for the time. Is there anyway around it? I don't necessarily need to use performance.now(). I just want to measure time in milliseconds.

我启动了 onclick 功能。当我第一次启动页面时它起作用。它在第二次点击时停止工作。t0 和 t1 得到相同的值,当我减去它们时,我得到了 0。反正周围有吗?我不一定需要使用 performance.now()。我只想以毫秒为单位测量时间。

Thank you.

谢谢你。

UpdateI think it has everything to do with the speed. For example:

更新我认为这与速度有关。例如:

    <html>
    <script type="text/javascript">
     function someFunction (){
        var t0 = performance.now();
        console.log(t0);
        //Function calculations
        //Some loop
        var counter = 0;
        for (i = 0; i < 1000000; i++) { 
         counter ++;
     }
        var t1 = performance.now();
        console.log(t1);
        console.log(t1 - t0);
    }
    
    </script>
    
    <button type="button" onclick="someFunction()">Click me</button>
    </hmtl>

Works as I would expect, but with the loop for (i = 0; i < 1000; i++)it doesn't.

像我期望的那样工作,但在循环中for (i = 0; i < 1000; i++)却没有。

Thank you for the pointers in the right direction.

感谢您提供正确方向的指示。

回答by jdphenix

The actual code you use will change the results here, and why the test comes to 0 as the result is a matter of speculation without that.

您使用的实际代码将改变这里的结果,以及为什么测试结果为 0 是一个推测问题,没有那个。

That said, micro benchmarks in JavaScript these days are subject to optimizations. For example:

也就是说,如今 JavaScript 中的微基准测试需要优化。例如:

function spiffy() {
    /* long bit of code that
       loops and loops and runs in 
       O(n!) time then finally */ 
    return result; 
}

Spiffy!

漂亮!

Let's say spiffy()deterministically always outputs the same result. The optimizer is allowed to effectively run this as:

假设spiffy()确定性地总是输出相同的结果。优化器可以有效地运行它:

function spiffy() { 
    return 42; 
}

Which turns

哪个转弯

function someFunction (){
    var t0 = performance.now();
    var result = spiffy();
    var t1 = performance.now();
    Console.log(t1 - t0);
}

into a useless test result.

变成无用的测试结果。

If you've got a bona-fide performance problem in your JavaScript app, I would profile it when it's running slower than molassesand analyze the busiest portions of your code. And I don't mean micro benchmarks, but examining run-time, look at the algorithmyou're using in that section and see if there might be a better one for your circumstances, and finally, ask someone else about the actual codein question, in the same contextit's running in.

如果您的 JavaScript 应用程序存在真正的性能问题,我会在它的运行速度比 molasses 慢时对其进行分析,并分析代码中最繁忙的部分。而且我不是指微基准测试,但检查的运行时间看看算法您使用的是一节,看看是否有可能是一个更好的为您的情况,最后,问别人对实际的代码中问题,它在相同的上下文中运行。

回答by Naor Tedgi

performance.now() upgraded and the question should be closed and not being bumpedanymore

performance.now()升级,这个问题应该被关闭,没有被撞到

https://developer.mozilla.org/en-US/docs/Web/API/Performance/now

https://developer.mozilla.org/en-US/docs/Web/API/Performance/now

the timestamps returned by Performance.now() are not limited to one-millisecond resolution. Instead, they represent times as floating-point numbers with up to microsecond precision.

Performance.now() 返回的时间戳不限于一毫秒的分辨率。相反,它们将时间表示为精度高达微秒的浮点数。

  <html>
        <script type="text/javascript">
         function someFunction (){
            var t0 = performance.now();
            console.log(t0);
            //Function calculations
            //Some loop
            var counter = 0;
            for (i = 0; i < 1000; i++) { 
             counter ++;
         }
            var t1 = performance.now();
            console.log(t1);
            console.log(t1 - t0);
        }
        
        </script>
        
        <button type="button" onclick="someFunction()">Click me</button>
        </hmtl>

回答by alphakevin

According to MDN doc:

根据 MDN 文档:

https://developer.mozilla.org/en-US/docs/Web/API/Performance/now

https://developer.mozilla.org/en-US/docs/Web/API/Performance/now

The timestamp is not actually high-resolution. To mitigate security threats such as Spectre, browsers currently round the results to varying degrees. (Firefox started rounding to 1 millisecond in Firefox 60.) Some browsers may also slightly randomize the timestamp. The precision may improve again in future releases; browser developers are still investigating these timing attacks and how best to mitigate them.

时间戳实际上不是高分辨率的。为了减轻 Spectre 等安全威胁,浏览器目前会在不同程度上对结果进行四舍五入。(Firefox 在 Firefox 60 中开始四舍五入到 1 毫秒。)一些浏览器也可能会稍微随机化时间戳。在未来的版本中,精度可能会再次提高;浏览器开发人员仍在研究这些定时攻击以及如何最好地缓解它们。

In such case you should not rely on performance.now()in browsers, or only rely it in millisecond resolution (like Date.now()does).

在这种情况下,你不应该依赖performance.now()浏览器,或者只依赖毫秒级的分辨率(就像Date.now()做的那样)。

One workaround, wrapping your code with another for{}loop with 1000 times, so the time spend on the wrapped code is roughly 1000 times of the original code.

一种解决方法是,用另一个for{}循环将代码包装1000 次,因此在包装代码上花费的时间大约是原始代码的 1000 倍。

function benchmark(func) {
  var start = Date.now()
  for (var i=0;i<1000;i++) {
    func();
  }
  var end = Date.now();
  var diff = (end - start) / 1000;
  console.log('running 1000 times, average time is '+ diff + 'ms');
}
benchmark(someFunction);

Or you can test your code in NodeJS, if your code has no DOM operation:

或者你可以在 NodeJS 中测试你的代码,如果你的代码没有 DOM 操作: