Exceptionally slow Javascript loop

javascript, loops, performance

Solution

The reason why only the `for` loop is so slow is because it's the only correct test case; all the other test cases never reset, amongst others, the value of `d`, so the first iteration is normal and the rest is obviously super fast :)

This jsperf gives a better outcome, whereby the for-loop is only slightly slower than the fastest result.

Update

As bfavaretto suggested, you should also reset `s` and the target array that you're building for a more consistent result. His results can be found here.

Problem

This is, in a way, a follow-up to my previous question. I created a jsPerf which compares a number of ways to take a 1-dimensional array of RGB pixel values ``` var rgb = [R, G, B, R, G, B...] ``` And convert those into RGBA values for an HTML5 canvas (where the alpha channel is always 255, fully opaque). ``` var rgba = [R, G, B, 255, R, G, B, 255...] ``` In my tests, I found that one of the loops I tested, titled "For Loop", is astronomically slower than the other loops. Where other loops were completing the operation hundreds of millions of times per second, it weighed in at a whopping 86 times per second. The loop can be found in the jsPerf link above, but here's a bit of code with "For Loop" and "4*unrolled, skip alpha", one of the faster loops in the test. ``` //Setup for each test function newFilledArray(length, val) { var array = Array(length); for (var i = 0; i < length; i++) { array[i] = val; } return array; } var w = 160; //width var h = 144; //height var n = 4 * w * h; //number of length of RGBA arrays var s = 0, d = 0; //s is the source array index, d is the destination array index var rgba_filled = newFilledArray(w*h*4, 255); //an RGBA array to be written to a canvas, prefilled with 255's (so writing to the alpha channel can be skipped var rgb = newFilledArray(w*h*3, 128); //our source RGB array (from an emulator's internal framebuffer) //4*unrolled, skip alpha - loop completes (exits) 185,693,068 times per second while (d < n) { rgba_filled[d++] = rgb[s++]; rgba_filled[d++] = rgb[s++]; rgba_filled[d++] = rgb[s++]; d++; } //For Loop - loop completes (exits) 85.87 times per second for (var d = 0; d < n; ++d) { rgba_filled[d++] = rgb[s++]; rgba_filled[d++] = rgb[s++]; rgba_filled[d++] = rgb[s++]; } ``` How can it be so incredibly similar in syntax, yet is so far removed in terms of performance?

Original source

Related problems