0

I found myself on this jsperfs' page, why does that happen?

JSPerf smallest timeout

Any clues? And why is 4 faster than 0 too?

Dave Newton
  • 158,873
  • 26
  • 254
  • 302
Rogerio Chaves
  • 2,719
  • 2
  • 25
  • 24
  • Re: 0 v 4, it isn't. In other words, it's a meaningless micro-benchmark, and 0 runs faster for me, consistently. – Dave Newton Mar 18 '14 at 16:17
  • In short, 0, 4 and BIG VALUE give about the same results because they are all converted to the minimum timeout value - 4ms. The BIG VALUE does this because it's larger than the 32 bit int setTimeout can get as parameter. – Tibos Mar 18 '14 at 16:18
  • Isn't the accuracy of JS time [~15 milliseconds](http://ejohn.org/blog/accuracy-of-javascript-time/)? – Elliott Frisch Mar 18 '14 at 16:21

2 Answers2

2

There is a comment about this, you should read the article closely.

Info

The smallest setTimeout timeout value allowed by the HTML5 specification is 4 ms. Smaller
values should clamp to 4 ms.

Therefore, the first two tests below should have about the same result.

P.S. Some browsers freak out when you use a value greater than 599147937791 for the 
timeout (i.e. they use 0 or 4 ms instead), hence the last test.

Essentially, Javascript has internal handling for 0 and 599147937792 as they qualify for over/underflow values for setTimeout and they are rounded to a default minimum accepted value 4 ms. This is probably because it is unreasonable to ask for a 0 ms delay as it would probably take longer than this to even process the function and determine this is what the user wants. The error on the larger value is probably due to the fact that computers have limits how big/small of a number that you can represent.

To understand why the large and small values return after 4 for example is that the internal handling takes time as well, a very small amount, but time. Consider these two timelines:

Timeline 1

  1. setTimeout(...,0) is called
  2. The function checks boundary conditions (something like if (time < 4) {// use 4})
  3. The function needs an extra step here to change the value from 0 -> 4.
  4. Now it sets the timeout for 4 ms

Timeline 2

  1. setTimeout(...,4) is called
  2. The function checks boundary conditions (something like if (time < 4) {// use 4})
  3. Everything is ok, moves along.
  4. Now it sets the timeout for 4 ms

Step 3 in the two timelines takes longer in the first case as there is the extra step of changing the value. Both will wait for the same amount of time, but the second one will start its timing ever so slightly sooner. This is much the same with 599147937792, except the check will be for the upper bound.

The phrasing "freaks out" makes me think it might look more like

try { 
    // try with the given input
} catch (Exception) {
    // Ahh I freaked out, just use 4 instead!!!!111!!!
}
Farmer Joe
  • 6,020
  • 1
  • 30
  • 40
1

From MDN:

Browsers including Internet Explorer, Chrome, Safari, and Firefox store the delay as a 32-bit signed Integer internally. This causes an Integer overflow when using delays larger than 2147483647, resulting in the timeout being executed immediately.

mbcrute
  • 1,117
  • 1
  • 11
  • 19