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 un
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]) );
Or you could do it the evil way.
var a = [1,2,3,4,5,6,7,8,9];
sum = eval(a.join("+"));
;)
I tried using performance.now() to analyze the performance of the different types of loops. I took a very large array and found the sum of all elements of the array. I ran the code three times every time and found forEach and reduce to be a clear winner.
// For loop
let arr = [...Array(100000).keys()]
function addUsingForLoop(ar){
let sum = 0;
for(let i = 0; i < ar.length; i++){
sum += ar[i];
}
console.log(`Sum: ${sum}`);
return sum;
}
let t1 = performance.now();
addUsingForLoop(arr);
let t2 = performance.now();
console.log(`Time Taken ~ ${(t2 - t1)} milliseconds`)
// "Sum: 4999950000"
// "Time Taken ~ 42.17500000959262 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 44.41999999107793 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 49.845000030472875 milliseconds"
// While loop
let arr = [...Array(100000).keys()]
function addUsingWhileLoop(ar){
let sum = 0;
let index = 0;
while (index < ar.length) {
sum += ar[index];
index++;
}
console.log(`Sum: ${sum}`)
return sum;
}
let t1 = performance.now();
addUsingWhileLoop(arr);
let t2 = performance.now();
console.log(`Time Taken ~ ${(t2 - t1)} milliseconds`)
// "Sum: 4999950000"
// "Time Taken ~ 44.2499999771826 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 44.01999997207895 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 41.71000001952052 milliseconds"
// do-while
let arr = [...Array(100000).keys()]
function addUsingDoWhileLoop(ar){
let sum = 0;
let index = 0;
do {
sum += index;
index++;
} while (index < ar.length);
console.log(`Sum: ${sum}`);
return sum;
}
let t1 = performance.now();
addUsingDoWhileLoop(arr);
let t2 = performance.now();
console.log(`Time Taken ~ ${(t2 - t1)} milliseconds`)
// "Sum: 4999950000"
// "Time Taken ~ 43.79500000504777 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 43.47500001313165 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 47.535000019706786 milliseconds"
// Reverse loop
let arr = [...Array(100000).keys()]
function addUsingReverseLoop(ar){
var sum=0;
for (var i=ar.length; i--;) {
sum+=arr[i];
}
console.log(`Sum: ${sum}`);
return sum;
}
let t1 = performance.now();
addUsingReverseLoop(arr);
let t2 = performance.now();
console.log(`Time Taken ~ ${(t2 - t1)} milliseconds`)
// "Sum: 4999950000"
// "Time Taken ~ 46.199999982491136 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 44.96500000823289 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 43.880000011995435 milliseconds"
// Reverse while loop
let arr = [...Array(100000).keys()]
function addUsingReverseWhileLoop(ar){
var sum = 0;
var i = ar.length;
while (i--) {
sum += ar[i];
}
console.log(`Sum: ${sum}`);
return sum;
}
var t1 = performance.now();
addUsingReverseWhileLoop(arr);
var t2 = performance.now();
console.log(`Time Taken ~ ${(t2 - t1)} milliseconds`)
// "Sum: 4999950000"
// "Time Taken ~ 46.26999999163672 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 42.97000000951812 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 44.31500000646338 milliseconds"
// reduce
let arr = [...Array(100000).keys()]
let t1 = performance.now();
sum = arr.reduce((pv, cv) => pv + cv, 0);
console.log(`Sum: ${sum}`)
let t2 = performance.now();
console.log(`Time Taken ~ ${(t2 - t1)} milliseconds`)
// "Sum: 4999950000"
// "Time Taken ~ 4.654999997001141 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 5.040000018198043 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 4.835000028833747 milliseconds"
// forEach
let arr = [...Array(100000).keys()]
function addUsingForEach(ar){
let sum = 0;
ar.forEach(item => {
sum += item;
})
console.log(`Sum: ${sum}`);
return sum
}
let t1 = performance.now();
addUsingForEach(arr)
let t2 = performance.now();
console.log(`Time Taken ~ ${(t2 - t1)} milliseconds`)
// "Sum: 4999950000"
// "Time Taken ~ 5.315000016707927 milliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 5.869999993592501 mienter code herelliseconds"
// "Sum: 4999950000"
// "Time Taken ~ 5.405000003520399 milliseconds"
While searching for the best method to sum an array, I wrote a performance test.
In Chrome, "reduce" seems to be vastly superior
I hope this helps
// Performance test, sum of an array
var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var result = 0;
// Eval
console.time("eval");
for(var i = 0; i < 10000; i++) eval("result = (" + array.join("+") + ")");
console.timeEnd("eval");
// Loop
console.time("loop");
for(var i = 0; i < 10000; i++){
result = 0;
for(var j = 0; j < array.length; j++){
result += parseInt(array[j]);
}
}
console.timeEnd("loop");
// Reduce
console.time("reduce");
for(var i = 0; i < 10000; i++) result = array.reduce(function(pv, cv) { return pv + parseInt(cv); }, 0);
console.timeEnd("reduce");
// While
console.time("while");
for(var i = 0; i < 10000; i++){
j = array.length;
result = 0;
while(j--) result += array[i];
}
console.timeEnd("while");
eval: 5233.000ms
loop: 255.000ms
reduce: 70.000ms
while: 214.000ms
What about summing both extremities? It would cut time in half. Like so:
1, 2, 3, 4, 5, 6, 7, 8; sum = 0
2, 3, 4, 5, 6, 7; sum = 10
3, 4, 5, 6; sum = 19
4, 5; sum = 28
sum = 37
One algorithm could be:
function sum_array(arr){
let sum = 0,
length = arr.length,
half = Math.floor(length/2)
for (i = 0; i < half; i++) {
sum += arr[i] + arr[length - 1 - i]
}
if (length%2){
sum += arr[half]
}
return sum
}
It performs faster when I test it on the browser with performance.now()
.
I think this is a better way. What do you guys think?
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.
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.
I started a JSPerf for array summations. It was quickly constructed and not guaranteed to be complete or accurate, but that's what edit is for :)