最快的 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 06:03:11  来源:igfitidea点击:

Fastest JavaScript summation

javascriptarraysfunction

提问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);

Source

来源

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.

然后来了forEachreduce它们具有几乎相同的性能并且因浏览器而异,但无论如何它们的性能最差。

回答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 次代码,发现forEachreduce是一个明显的赢家。

// 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()