views:

139

answers:

4

What is the fastest way to sum up an array in JavaScript? A quick search turns over a few different methods, but I would like a native solution if possible. This will run under SpiderMonkey.

Thinking very inside-the-box I have been using:

var count = 0;
for(var i = 0; i < array.length; i++)
{
    count = count + array[i];
}

I'm sure there is a better way then straight iteration.

+3  A: 

You should be able to use reduce.

var sum = array.reduce(function(pv, cv) { return pv + cv; }, 0);

Source

ChaosPandion
... except in IE <= 8.
Tim Down
According to the linked documentation, "[reduce] may not be available in all browsers"
Ryan Kinal
@Tim: Again, this is running under SpiderMonkey, not any particular browser.
Josh K
Ah, sorry, I missed that. In which case this is the answer.
Tim Down
Somehow I doubt it, even though `reduce` is a native function. In performance oriented code in JS, avoiding function calls is almost always faster,
MooGoo
@MooGoo - From my experience the overhead of function calls mostly comes from member look up.
ChaosPandion
array.reduce is great in Firebug Console, but is very slow on other browsers when compared to the other solutions (see my JSFiddle).
vol7ron
MooGoo: you may well be right. I confess I didn't test and just assumed the native method would be fatser.
Tim Down
+1  A: 

The fastest loop, according to this test is a while loop in reverse

var i = arr.length; while (i--) { }

So, this code might be the fastest you can get

Array.prototype.sum = function () {
    var total = 0;
    var i = arr.length; 

    while (i--) {
        total += this[i];
    }

    return total;
}

Array.prototype.sum adds a sum method to the array class... you could easily make it a helper function instead.

Chad
My reverse for is slightly faster, more times than not.
vol7ron
@vol7ron, very, very, very marginally, we're talking ~1ms over a 1000 records
Chad
:) yes yes and not every time either. still, I'm more likely to use `for(var i=0,n=a.length;i<n;i++){}` due to the start/stop control structure.
vol7ron
+2  A: 

Improvements


Your looping structure could be made faster:


   var count = 0;
   for(var i=0, n=array.length; i < n; i++) 
   { 
      count += array[i]; 
   }

This retrieves array.length once, rather than with each iteration. The optimization is made by caching the value.


If you really want to speed it up:


   var count=0;
   for (var i=array.length; i--;) {
     count+=array[i];
   }

This is equivalent to a while reverse loop. It caches the value and is compared to 0, thus faster iteration.

For a more complete comparison list, see my JSFiddle.
Note: array.reduce is horrible there, but in Firebug Console it is fastest.

vol7ron
+1  A: 

For your specific case, just use the reduce method of Arrays:

var sumArray = function() {
    // Use one adding function rather than create a new one each
    // time sumArray is called
    function add(a, b) {
        return a + b;
    }

    return function(arr) {
        return arr.reduce(add);
    };
}();

alert( sumArray([2, 3, 4]) );
Tim Down