最快的 JavaScript 求和
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3762589/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Fastest JavaScript summation
提问by Josh K
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.
在 JavaScript 中总结数组的最快方法是什么?快速搜索会转换几种不同的方法,但如果可能的话,我想要一个本机解决方案。这将在 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.
我确信有比直接迭代更好的方法。
回答by ChaosPandion
You should be able to use reduce.
您应该可以使用reduce.
var sum = array.reduce(function(pv, cv) { return pv + cv; }, 0);
And with arrow functionsintroduced in ES6, it's even simpler:
加上ES6 中引入的箭头函数,就更简单了:
sum = array.reduce((pv, cv) => pv + cv, 0);
回答by vol7ron
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.lengthonce, rather than with each iteration. The optimization is made by caching the value.
这检索array.length一次,而不是每次迭代。通过缓存值进行优化。
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.
这相当于一个while反向循环。它缓存该值并与 0 进行比较,从而加快迭代速度。
For a more complete comparison list, see my JSFiddle.
Note:array.reduce is horrible there, but in Firebug Console it is fastest.
有关更完整的比较列表,请参阅我的JSFiddle。
注意:array.reduce 在那里很糟糕,但在 Firebug 控制台中它是最快的。
Compare Structures
比较结构
I started a JSPerffor array summations. It was quickly constructed and not guaranteed to be complete or accurate, but that's what editis for :)
我开始了一个用于数组求和的 JSPerf。它是快速构建的,不能保证完整或准确,但这就是编辑的目的:)
回答by Inkh Su Tesou
While searching for the best method to sum an array, I wrote a performance test.
在寻找对数组求和的最佳方法时,我编写了一个性能测试。
In Chrome, "reduce" seems to be vastly superior
在 Chrome 中,“减少”似乎要优越得多
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
评估:5233.000 毫秒
loop: 255.000ms
循环:255.000 毫秒
reduce: 70.000ms
减少:70.000ms
while: 214.000ms
同时:214.000 毫秒
回答by Kodejuice
Or you could do it the evil way.
或者你可以用邪恶的方式来做。
var a = [1,2,3,4,5,6,7,8,9];
sum = eval(a.join("+"));
;)
;)
回答by CaffGeek
The fastest loop, according to this testis a while loop in reverse
最快的循环,根据这个测试是反向的while循环
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 = this.length;
while (i--) {
total += this[i];
}
return total;
}
Array.prototype.sumadds a sum method to the array class... you could easily make it a helper function instead.
Array.prototype.sum向数组类添加一个 sum 方法……您可以轻松地将其改为辅助函数。
回答by Tim Down
For your specific case, just use the reducemethod of Arrays:
对于您的具体情况,只需使用reduceArrays的方法:
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]) );
回答by BrunoLM
Based on this test (for-vs-forEach-vs-reduce)and this (loops)
基于这个测试(for-vs-forEach-vs-reduce)和这个(循环)
I can say that:
我可以说:
1# Fastest: for loop
1# 最快:for 循环
var total = 0;
for (var i = 0, n = array.length; i < n; ++i)
{
total += array[i];
}
2# Aggregate
2# 聚合
For you case you won't need this, but it adds a lot of flexibility.
对于你的情况,你不需要这个,但它增加了很多灵活性。
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;
};
Usage:
用法:
var total = array.Aggregate(function(a,b){ return a + b });
Inconclusive methods
不确定的方法
Then comes forEachand reducewhich have almost the same performance and varies from browser to browser, but they have the worst performance anyway.
然后来了forEach,reduce它们具有几乎相同的性能并且因浏览器而异,但无论如何它们的性能最差。
回答by cesarvargas
What about summing both extremities? It would cut time in half. Like so:
两端求和怎么样?它会将时间减少一半。像这样:
1, 2, 3, 4, 5, 6, 7, 8; sum = 0
1、2、3、4、5、6、7、8;总和 = 0
2, 3, 4, 5, 6, 7; sum = 10
2、3、4、5、6、7;总和 = 10
3, 4, 5, 6; sum = 19
3、4、5、6;总和 = 19
4, 5; sum = 28
4、5;总和 = 28
sum = 37
总和 = 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?
当我在浏览器上使用performance.now(). 我认为这是一个更好的方法。你们有什么感想?
回答by Ankur Singh
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 forEachand reduceto be a clear winner.
我尝试使用 performance.now() 来分析不同类型循环的性能。我拿了一个非常大的数组,找到了数组所有元素的总和。我每次都运行了 3 次代码,发现forEach和reduce是一个明显的赢家。
// For loop
// 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 loop
//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"
// 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
// 反转while循环
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
// 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"
回答by espiralis
one of the simplest, fastest, more reusable and flexible is:
最简单、最快、更可重用和灵活的方法之一是:
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()

