Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are these Javascript for loops significantly slower on Firefox then Chrome / Safari?

I was messing around with the benchmark site jfprefs and created my own benchmark at http://jsperf.com/prefix-or-postfix-increment/9.

The benchmarks are variations of Javascript for loops, using prefix and postfix incrementors and the Crockford jslint style of not using an in place incrementor.

for (var index = 0, len = data.length; index < len; ++index) {
  data[index] = data[index] * 2;
}

for (var index = 0, len = data.length; index < len; index++) {
  data[index] = data[index] * 2;
}

for (var index = 0, len = data.length; index < len; index += 1) {
  data[index] = data[index] * 2;
}

After getting the numbers from a couple of runs of the benchmark, I noticed that Firefox is doing about 15 operations per second on average and Chrome is doing around 300.

benchmark results

I thought JaegerMonkey and v8 were fairly comparable in terms of speed? Are my benchmarks flawed somehow, is Firefox doing some kind of throttling here or is the gap really that large between the performance of the Javascript interpreters?

UPDATE: Thanks to jfriend00, I've concluded the difference in performance is not entirely due to the loop iteration, as seen in this version of the test case. As you can see Firefox is slower, but not as much of a gap as we see in the initial test case.

So why is the statement,

data[index] = data[index] * 2;

So much slower on Firefox?

like image 593
James McMahon Avatar asked Sep 08 '12 04:09

James McMahon


People also ask

Why is Firefox so slow compared to Chrome?

I found that Firefox used more RAM than Chrome, which not only debunks Mozilla's claims but comes as a huge surprise considering Chrome's reputation as a computer performance killer. With this in mind, Firefox is likely to slow down your computer faster than Chrome is.

Are for loops slow Javascript?

The for , while , and do-while loops all have similar performance characteristics, and so no one loop type is significantly faster or slower than the others.


1 Answers

Arrays are tricky in JavaScript. The way you create them, how you fill them (and with what values) can all affect their performance.

There are two basic implementations that engines use. The simplest, most obvious one is a contiguous block of memory (just like a C array, with some metadata, like the length). It's the fastest way, and ideally the implementation you want in most cases.

The problem is, arrays in JavaScript can grow very large just by assigning to an arbitrary index, leaving "holes". For example, if you have a small array:

var array = [1,2,3];

and you assign a value to a large index:

array[1000000] = 4;

you'll end up with an array like this:

[1, 2, 3, undefined, undefined, undefined, ..., undefined, 4]

To save memory, most runtimes will convert array into a "sparse" array. Basically, a hash table, just like regular JS objects. Once that happens, reading or writing to an index goes from simple pointer arithmetic to a much more complicated algorithm, possibly with dynamic memory allocation.

Of course, different runtimes use different heuristics to decide when to convert from one implementation to another, so in some cases, optimizing for Chrome, for example, can hurt performance in Firefox.

In your case, my best guess is that filling the array backwards is causing Firefox to use a sparse array, making it slower.

like image 75
Matthew Crumley Avatar answered Sep 17 '22 08:09

Matthew Crumley