web-dev-qa-db-ja.com

最速のJavaScript合計

JavaScriptで配列を要約する最も速い方法は何ですか?クイック検索では いくつかの異なる方法 が有効になりますが、可能であればネイティブソリューションが必要です。これはSpiderMonkeyの下で実行されます。

私が使用している非常に内側のボックスを考える:

var count = 0;
for(var i = 0; i < array.length; i++)
{
    count = count + array[i];
}

まっすぐな反復よりも良い方法があると確信しています。

63
Josh K

reduceを使用できるはずです。

var sum = array.reduce(function(pv, cv) { return pv + cv; }, 0);

ソース

ES6で導入された 矢印関数 を使用すると、さらに簡単になります。

sum = array.reduce((pv, cv) => pv + cv, 0);
122
ChaosPandion

改善点


ループ構造を高速化できます。


   var count = 0;
   for(var i=0, n=array.length; i < n; i++) 
   { 
      count += array[i]; 
   }

これにより、array.length 1回(各反復ではなく)。最適化は、値をキャッシュすることにより行われます。


本当にスピードアップしたい場合:


   var count=0;
   for (var i=array.length; i--;) {
     count+=array[i];
   }

これは、while逆ループと同等です。値をキャッシュし、0と比較されるため、反復が高速になります。

より完全な比較リストについては、myJSFiddleを参照してください。
注:array.reduceは恐ろしいですが、Firebugコンソールでは最速です。


構造を比較する

配列の合計に対してJSPerfを開始しました。それはすぐに構築され、完全または正確であることが保証されていませんが、それはeditの目的です:)

30
vol7ron

配列を合計するのに最適な方法を探している間に、パフォーマンステストを作成しました。

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");

評価:5233.000ms

ループ:255.000ms

削減:70.000ms

while:214.000ms

20
Inkh Su Tesou

または、邪悪な方法でそれを行うことができます。

var a = [1,2,3,4,5,6,7,8,9];

sum = eval(a.join("+"));

;)

6
Kodejuice

このテスト による最速ループは、逆のwhileループです

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クラスを配列クラスに追加します...代わりに簡単にヘルパー関数にすることができます。

5
CaffGeek

特定のケースでは、配列の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]) );
2
Tim Down

このテスト(for-vs-forEach-vs-reduce) および this(loops) に基づく

私はそれを言うことができます:

1#最速:forループ

var total = 0;

for (var i = 0, n = array.length; i < n; ++i)
{
    total += array[i];
}

2#集計

あなたの場合、これは必要ありませんが、多くの柔軟性を追加します。

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 });

決定的でない方法

次にforEachreduceが登場します。これらはほとんど同じパフォーマンスを持ち、ブラウザーによって異なりますが、いずれにしてもパフォーマンスは最悪です。

1
BrunoLM

両方の四肢を合計するのはどうですか?時間を半分に短縮できます。そのようです:

1、2、3、4、5、6、7、8;合計= 0

2、3、4、5、6、7;合計= 10

3、4、5、6;合計= 19

4、5;合計= 28

合計= 37

1つのアルゴリズムは次のとおりです。

_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()を使用してブラウザーでテストすると、パフォーマンスが向上します。これはもっと良い方法だと思います。皆さんはどう思いますか?

0
cesarvargas

最も単純で、最速で、再利用可能で柔軟なものの1つは次のとおりです。

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()
0
espiralis