Since it is nearly impossible to find up to date statistical data on the various javascript speedhacks (in google the first three ones are from 2003-2006), I decided to do a quick and dirty test to see how fast the while(i–){} method is (since for in should only be used with objects, I’m not going to test that, period).
This is 1000*1000 iterations, done 5 times and averaged (each one is relative to its own browser); first one is vanilla for, second is length property stored beforehand, third is reversed while as seen above:
chrome 3: 0: 100% 1: 42.86% 2: 41.07%
safari 4: 0: 100% 1: 50% 2: 50.11%
ff 2.0: 0: 100% 1: 69.07% 2: 45.09%
ff 3.0.3: 0: 100% 1: 82.37% 2: 48.44%
ff 3.5.6: 0: 100% 1: 153.56% 2: 154.9%
ff 3.5.6*: 0: 100% 1: 151.85% 2: 159.26%
opera 9: 0: 100% 1: 83.26% 2: 64.93%
opera 10: 0: 100% 1: 81.67% 2: 69.26%
ie8**: 0: 100% 1: 35% 2: 29%
*: portable install, no extensions
**: only one test, the rest did not work
Now, oh my, these are some interesting numbers. If you check this simple test directly, you can test for milliseconds – have some fun; my conclusions:
- First of all, Safari 4 (and bleeding edge webkit) is lightning fast. Honestly, I’m not even sure if I want to optimize there, because it’s unbeatable.
- Internet Explorer (6,7,8, you name it) is a shame; period. In version 8 I couldn’t disable the annoyingly short script execution timeout (which can be disabled in the registry for 5.5/6/7) and I did not want to do burst measurements via setTimeouts, so out of the six tests only the simplest worked and the durations are utter crap. No words can express my sadness seeing this underdog browser.
- To my greatest surprise Firefox 3.5 literally hates these optimization attempts. I totally don’t understand what’s going on, but using while just for making a damn loop “faster” seems a very very bad idea here.
While and array length prefetching is (and shall be) faster, but we have enough quirks here to have a serious headache. Why? As we can see, hoping for the best while using “while” is not the way to go (it should be, I admit it though); a general solution would be using a wrapper function (forEach/each), BUT that would be much slower (because of the function callback) – while being nicer. Unless in one case, which is the most common case: arrays and native forEach – Webkit, Opera, Firefox, they all support it. Internet Explorer does not – nothing new.
In the end this means that a clean forEach wrapper function (like with the javascript libraries) speedwise is not good (and I’m being very polite here), but checking for the native forEach (in case of arrays) and deciding which solution to use in place is a waste of code and is serious readability rape.
So, in the end, though only with a tiny margin, I still say that premature optimization is evil – we have no holy grail method in the world of browser quirks; and even if we have, it will go sour in a couple of months.