Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exceptionally slow Javascript loop

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?

like image 432
Trey Keown Avatar asked Jul 09 '13 03:07

Trey Keown


People also ask

How do you slow down a loop in JavaScript?

Just put the timeout in the for-loop, and the loop is less fast: When we run the code with setTimeout, the following happens: nothing happens for 1 second; then all the logs come up in a flash.

Which loop is more efficient in JavaScript?

forEach loop The forEach method in Javascript iterates over the elements of an array and calls the provided function for each element in order. The execution time of forEach is dramatically affected by what happens inside each iteration. It is fast and designed for functional code.

Which loop is faster in JavaScript language?

You can see that for loops are 3 time faster than array methods like forEach map and reduce . Upon receiving an array element, array methods execute a callback function for each element.

Is for loop faster than Map JavaScript?

Even with these simple tests, loops are almost three times faster.


1 Answers

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.

like image 179
Ja͢ck Avatar answered Oct 18 '22 02:10

Ja͢ck