Heads up on Javascript loop performance in Prototype

For people out there are using Prototype’s enumerable methods, be aware they come at a large performance cost.

Some quick tests in Firefox 2 showed the performance difference for 1000 loops over a 100 item array:

var array = $R(0, 100).toArray();

for (var i = 0, length = array.length; i < length; i++)

~30ms

for (var i = 0; i < array.length; i++)

~60ms

Using Firefox’s built-in forEach array method:

array.forEach(function() {})

~230ms

And finally Prototype’s each method:

array.each(function() {})

500ms

In this case, Prototype’s each method is over 16 times slower than the fastest for() version. Most of the time this won’t matter, but if you’re doing anything loop-intensive, be aware!

-Jonathan.

Jonathan Viney wrote:

For people out there are using Prototype's enumerable methods, be aware they come at a large performance cost.

I think this is mainly due to the try-catch block that each iteration is surrounded by to catch the $continue and $break exceptions to simulate proper control statements. Also the added overhead of the function call doesn't help matters either.

For really sensitive areas that use "each" and don't use $break or $continue you could use "_each" which should be a bit faster as it doesn't have the try-catch block. This is the internal method that each() calls on the actual enumerable object to do its iteration. I find the flexibility of methods like map(), findAll(), reject(), etc. that Enumerable provides well worth the performance hit.

Eric

Very true, most of the time the benefits are worth the performance hit.

I didn’t include _each because it looked like it was supposed to be a private method because of the _ prefix. Interestingly enough, _each is actually noticeably faster than Firefox’s built-in forEach method (180ms compared to 230ms), but still 6 times slower than the fastest for() loop.

-Jonathan.