在JavaScript中总结数组的最快方法是什么?快速搜索会翻转a few different methods,但如果可能的话,我想要一个原生解决方案。这将在SpiderMonkey下运行。
在我一直在使用的方式内思考:
var count = 0;
for(var i = 0; i < array.length; i++)
{
count = count + array[i];
}
我确信有更好的方法然后直接迭代。
答案 0 :(得分:119)
您应该可以使用reduce
。
var sum = array.reduce(function(pv, cv) { return pv + cv; }, 0);
在ES6中引入arrow functions,它甚至更简单:
sum = array.reduce((pv, cv) => pv + cv, 0);
答案 1 :(得分:30)
var count = 0;
for(var i=0, n=array.length; i < n; i++)
{
count += array[i];
}
这将检索array.length
一次,而不是每次迭代。通过缓存值来进行优化。
var count=0;
for (var i=array.length; i--;) {
count+=array[i];
}
这相当于一段时间的反向循环。它缓存该值并与0进行比较,从而加快迭代速度。
要获得更完整的比较列表,请参阅我的 JSFiddle 注意: array.reduce在那里很糟糕,但在Firebug Console中它是最快的。
我开始使用 JSPerf 进行数组求和。它很快被构建,并不能保证完整或准确,但这就是编辑用于:)
答案 2 :(得分:20)
在搜索对数组求和的最佳方法时,我编写了一个性能测试。
在Chrome中,“减少”似乎非常优越
我希望这会有所帮助
// 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
循环:255.000ms
减少:70.000ms
while:214.000ms
答案 3 :(得分:5)
根据this test,最快的循环是反向循环
var i = arr.length; while (i--) { }
所以,这段代码可能是你能获得的最快的代码
Array.prototype.sum = function () {
var total = 0;
var i = this.length;
while (i--) {
total += this[i];
}
return total;
}
Array.prototype.sum
为数组类添加了一个sum方法......你可以轻松地将它作为辅助函数。
答案 4 :(得分:3)
或者你可以用邪恶的方式做到这一点。
var a = [1,2,3,4,5,6,7,8,9];
sum = eval(a.join("+"));
)
答案 5 :(得分:2)
针对您的具体情况,只需使用数组的reduce
方法:
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]) );
答案 6 :(得分:1)
基于this test (for-vs-forEach-vs-reduce)和this (loops)
我可以这样说:
var total = 0;
for (var i = 0, n = array.length; i < n; ++i)
{
total += array[i];
}
对于你的情况你不需要这个,但它增加了很多灵活性。
Array.prototype.Aggregate = function(fn) {
var current
, length = this.length;
if (length == 0) throw "Reduce of empty array with no initial value";
current = this[0];
for (var i = 1; i < length; ++i)
{
current = fn(current, this[i]);
}
return current;
};
用法:
var total = array.Aggregate(function(a,b){ return a + b });
然后forEach
和reduce
具有几乎相同的性能,并且因浏览器而异,但无论如何它们的性能最差。
答案 7 :(得分:0)
最简单,最快速,更可重复和最灵活的一个是:
Array.prototype.sum = function () {
for(var total = 0,l=this.length;l--;total+=this[l]); return total;
}
// usage
var array = [1,2,3,4,5,6,7,8,9,10];
array.sum()
答案 8 :(得分:0)
两个末端相加怎么办?这样可以将时间缩短一半。像这样:
1,2,3,4,5,6,7,8;总和= 0
2、3、4、5、6、7;总和= 10
3,4,5,6;总和= 19
4,5;总和= 28
sum = 37
一种算法可能是:
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
}
当我使用performance.now()
在浏览器中对其进行测试时,它的执行速度更快。
我认为这是一种更好的方法。你们怎么看?
答案 9 :(得分:0)
我尝试使用performance.now()分析不同类型的循环的性能。我采用了一个非常大的数组,并发现了数组中所有元素的总和。我每次都运行了三次代码,发现 forEach 和 reduce 是明显的赢家。
// For循环
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循环
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"
//做一会儿
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"
//反向循环
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"
//反向循环
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"
//减少
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"