最快的 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.length
once, 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.sum
adds 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 reduce
method of Arrays:
对于您的具体情况,只需使用reduce
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]) );
回答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 forEach
and reduce
which 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()