Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Timing with javascript performance.now()

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:

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.

Thank you.

Update I 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.

Thank you for the pointers in the right direction.

like image 558
slrom Avatar asked Apr 05 '15 17:04

slrom


People also ask

What is performance now () JavaScript?

In JavaScript performance. now() method can be used to check the performance of your code. You can check the execution time of your code using this method. It returns the value of time (of type double) in milliseconds.

Is performance now in milliseconds?

now() The performance. now() method returns a DOMHighResTimeStamp , measured in milliseconds.

Do we ever need to use performance now ()` Or can we just use the Date object?

No! Date. now() returns the number of milliseconds elapsed since 1 January 1970 00:00:00 UTC, performance. now() returns the number of milliseconds/microseconds elapsed since an arbitrary epoch.


2 Answers

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.

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

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:

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 molasses and analyze the busiest portions of your code. And I don't mean micro benchmarks, but examining run-time, look at the algorithm you'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 code in question, in the same context it's running in.

like image 52
jdphenix Avatar answered Oct 23 '22 14:10

jdphenix


According to MDN doc:

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.

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

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.

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:

  • process.hrtime()
  • performance.now
like image 1
alphakevin Avatar answered Oct 23 '22 14:10

alphakevin