JavaScriptで配列をループする最も速い方法は何ですか?


248

私はあなたがこのようにループのために書くべきであることを本から学びました:

for(var i=0, len=arr.length; i < len; i++){
    // blah blah
}

そのため、arr.length毎回計算されません。

他の人は、コンパイラがこれに対していくらかの最適化を行うと言うので、あなたはただ書くことができます:

for(var i=0; i < arr.length; i++){
    // blah blah
}

私は実際にどちらが最善の方法であるか知りたいのですか?


1
配列のループを処理するときにも一見の価値があります:jsperf.com/array-loop-var-caching
cloakedninjas

@ wong2 TthisベンチマークからBrowserdietは、選択肢のより完全なコレクションを持っています。
ドミ2014年


以前のjsbenの改善:jsben.ch
Corbfon

for ... ofこの競争にループを導入できますか?構文はキャッシュなしのforループよりもさらに簡単なようです。forループの使用に切り替える必要があるかどうかを知りたいです。
プログラマ

回答:


339

最新のブラウザでこのテストを実行した後...

http://jsben.ch/dyM52

現在、ループの最速の形式です(私の意見では、構文的に最も明白です)。

長さをキャッシュする標準のforループ

for (var i = 0, len = myArray.length; i < len; i++) {

}

これは間違いなく私がJavaScriptエンジン開発者を称賛するケースだと思います。ランタイムは、はなく明確にするために最適化する必要があります。


6
興味深いことに、IE9では、これは高速である:(VAR iがLEN = myArray.length、= 0; I <lenの; ++ i)について{} //接頭辞INCR、代わりにPostfixの
クリストファーBennage

4
使用するその他の理由については、PostfixよりもPrefix演算子を優先するをご覧ください++i
Bennett McElwee

4
@BennettMcElweeが示唆したように、私はプレフィックス演算子を使用してテストし、それが少し速く走る: for(var i=0, len=myArray.length; i<len; ++i) チェックjsperf.com/caching-array-length/84を
victmo

21
このループの使用には注意が必要です。私はそれを使い始めましたが、1つの間違いのためにバグを追跡するのが困難でした。次のように2つのループをネストする場合:jsfiddle.net/KQwmL/1。2つのループでvar lenに異なる名前を付けるように注意する必要があります。そうしないと、2番目のループで最初のlenが上書きされます。
Rui Marques

6
@WillshawMedia 1つのvarステートメントで複数の変数を宣言できます。それがどのように書かlenれるかは、あなたが提案するように実際にスコープされます。
jondavidjohn 2013

90

JavaScript配列をループする絶対最速の方法は次のとおりです。

var len = arr.length;
while (len--) {
    // blah blah
}

完全な比較については、http://blogs.oracle.com/greimer/entry/best_way_to_code_aを参照してください


1
使用することを忘れないでくださいvar(そうでなければlenグローバル変数になります)。また、その他のループベンチマークについては、jsperf.com / loopsを参照してください。
Mathias Bynens、2011年

22
この回答が基づいているブログの投稿は、ほぼ4年前のものであり、その間にjsエンジンの多くが変更されました。更新された比較については、以下の私の回答を参照してください。
jondavidjohn 2011

1
@jondavidjohnに同意します。私はこのコードをテストしましたが、効率が悪いことがわかりました... jsperf.com/caching-array-length/84を確認してください
victmo

上記の答えは、ほとんどすべての場合(ブラウザ間で)、forループよりもはるかに低速です。受け入れられた回答のJSPerfリンクを参照してください。これは非常に残念です。非常に読みやすいIMOだからです。
Letharion 2013

3
@jondavidjohnの推測では、「以下の私の回答」が意味するのは「上記の私の回答」だと思います。
Shanimal 16

40

2016年6月の時点で、最新のChromeでいくつかのテストを行っています(2016年5月のブラウザ市場の71%、および増加中):

  • 最速のループはforループであり、キャッシュ長の有無にかかわらず、非常に似たパフォーマンスを提供します。(キャッシュされた長さのforループは、キャッシュがないものよりも良い結果をもたらす場合がありますが、その違いはほとんど無視できます。つまり、エンジンはすでに標準化され、おそらく最も単純なforループforキャッシュを優先するように最適化されている可能性があります)。
  • 減少を伴うwhileループは、forループよりも約1.5倍遅くなりました。
  • (標準のforEachのような)コールバック関数を使用したループは、forループよりも約10倍遅くなりました。

私はこのスレッドが古すぎると思いますし、長さをキャッシュする必要があると考えるか、パフォーマンスを向上させるためにデクリメント付きの逆トラバースwhilesを使用する必要があるとプログラマを誤解させ、単純なforループよりも読みにくく、エラーが発生しやすいコードを記述します。したがって、私はお勧めします:

  • アプリが多数のアイテムを反復処理する場合、またはループコードが頻繁に使用される関数内にある場合、単純なforループが答えです。

    for (var i = 0; i < arr.length; i++) {
      // Do stuff with arr[i] or i
    }
  • アプリが多くのアイテムを実際に反復しない場合、またはあちこちで小さな反復を行う必要がある場合、選択したJSライブラリの標準のforEachコールバックまたは同様の関数を使用すると、理解しやすくなり、エラーが発生しにくくなります。インデックス変数のスコープが閉じているため、ブラケットを使用する必要がなく、配列の値に直接アクセスします。

    arr.forEach(function(value, index) {
      // Do stuff with value or index
    });
  • 本当に数ミリ秒をスクラッチする必要があり、何十億もの行を繰り返し処理し、配列の長さがプロセスを通じて変化しない場合は、forループで長さをキャッシュすることを検討してください。今日これは本当に必要ないと思いますが:

    for (var i = 0, len = arr.length; i < len; i++) {
      // Do stuff with arr[i]
    }

いいえ。jsbench.github.io/#67b13d4e78cdd0d7a7346410d5becf12は、「ループ、キャッシュされた値、インラインコード」が76,635オペレーション/秒(Chrome 38.0.2125.111)しか得られなかったのに対し、最速は「逆ループ、暗黙の比較、インラインコード」(105,221オペレーション/秒)であることを示しています。 )
Fr0sT 2017

@ Fr0sTベンチマークは別のシナリオであり、配列をインデックス1から<=長さまでトラバースします。もちろん、これは異なる結果をもたらすでしょう。<長さでゼロベースの配列をトラバースしようとすると-これは通常のシナリオのようです-通常の "for"ループで結果がより最適化されていることがわかります(キャッシュされた長さはわずかに高速です)。
CGodo 2017

Kyopaxaはベンチマークを(0 <= i <長さ)に変更しました。結果は同じです。「逆ループ、暗黙比較、関数呼び出し」は365 kops /秒、「ループ、キャッシュ値、インラインコード」は350 kops /秒(FF 51)
Fr0sT

@ Fr0sTのように、等しい比較なしでゼロベースのキャッシュされたforループを変更すると、for(let i=0, j=array.length; i < j; i++)forループの転送が大幅に高速化します。いくつかのテストで実行したところ、ほとんどがエラーの範囲内または逆ループでした。
Isaac B

1
@IsaacBおよびすべて、申し訳ありませんが、ベンチが正しくないことに気づきませんでした。すべての直接ループは1..lengthを反復しますが、逆ループはlength..0を反復します(arr [length]項目は無効です)。テストを修正したところ、「ループ、インラインコード」360,616 ops /秒±0.27%、「ループ、キャッシュ値、インラインコード」345,786 ops /秒±2.18%(Sic!)「逆ループ、暗黙的な比較、インラインコード "322,640 ops / sec±2.90%(!!!)。テストはFF51によって実行されました。新しいベンチはこちらjsbench.github.io/#6bdfcd2692ba80c16a68c88554281570です。したがって、ループを醜くすることは意味がないようです。
Fr0sT 2017年

31

順序が重要でない場合、私はこのスタイルを好みます:

for(var i = array.length; i--; )

それは長さをキャッシュし、書くのにはるかに短いです。しかし、逆の順序で配列を反復処理します。


6
あなたはそれを殺しました。
Vignesh Raja

i> = 0は必要ありませんか?
MarwaAhmad

3
@MarwaAhmad:No. i--は数値を返します。数値が0条件になるとfalseBoolean(0) === falseです。
Felix Kling

30

それはちょうど2018年なので、アップデートは素晴らしいかもしれません...

そして私は本当に受け入れられた答え同意しなければなりません。異なるブラウザで延期されます。いくつかはforEachより速く、いくつfor-loopかはwhile ここにあり、ここにいくつかはすべてのメソッドのベンチマークですhttp://jsben.ch/mW36e

arr.forEach( a => {
  // ...
}

そして、for(a = 0; ... )そのようなforループの多くを見ることができるので、'var'変数がないとグローバルに定義され、これは速度に劇的に影響を及ぼして遅くなることを言及する価値があります。

ダフのデバイスはオペラでは高速に動作しますが、Firefoxでは動作しません

var arr = arr = new Array(11111111).fill(255);
var benches =     
[ [ "empty", () => {
  for(var a = 0, l = arr.length; a < l; a++);
}]
, ["for-loop", () => {
  for(var a = 0, l = arr.length; a < l; ++a)
    var b = arr[a] + 1;
}]
, ["for-loop++", () => {
  for(var a = 0, l = arr.length; a < l; a++)
    var b = arr[a] + 1;
}]
, ["for-loop - arr.length", () => {
  for(var a = 0; a < arr.length; ++a )
    var b = arr[a] + 1;
}]
, ["reverse for-loop", () => {
  for(var a = arr.length - 1; a >= 0; --a )
    var b = arr[a] + 1;
}]
,["while-loop", () => {
  var a = 0, l = arr.length;
  while( a < l ) {
    var b = arr[a] + 1;
    ++a;
  }
}]
, ["reverse-do-while-loop", () => {
  var a = arr.length - 1; // CAREFUL
  do {
    var b = arr[a] + 1;
  } while(a--);   
}]
, ["forEach", () => {
  arr.forEach( a => {
    var b = a + 1;
  });
}]
, ["for const..in (only 3.3%)", () => {
  var ar = arr.slice(0,arr.length/33);
  for( const a in ar ) {
    var b = a + 1;
  }
}]
, ["for let..in (only 3.3%)", () => {
  var ar = arr.slice(0,arr.length/33);
  for( let a in ar ) {
    var b = a + 1;
  }
}]
, ["for var..in (only 3.3%)", () => {
  var ar = arr.slice(0,arr.length/33);
  for( var a in ar ) {
    var b = a + 1;
  }
}]
, ["Duff's device", () => {
  var len = arr.length;
  var i, n = len % 8 - 1;

  if (n > 0) {
    do {
      var b = arr[len-n] + 1;
    } while (--n); // n must be greater than 0 here
  }
  n = (len * 0.125) ^ 0;
  if (n > 0) { 
    do {
      i = --n <<3;
      var b = arr[i] + 1;
      var c = arr[i+1] + 1;
      var d = arr[i+2] + 1;
      var e = arr[i+3] + 1;
      var f = arr[i+4] + 1;
      var g = arr[i+5] + 1;
      var h = arr[i+6] + 1;
      var k = arr[i+7] + 1;
    }
    while (n); // n must be greater than 0 here also
  }
}]];
function bench(title, f) {
  var t0 = performance.now();
  var res = f();
  return performance.now() - t0; // console.log(`${title} took ${t1-t0} msec`);
}
var globalVarTime = bench( "for-loop without 'var'", () => {
  // Here if you forget to put 'var' so variables'll be global
  for(a = 0, l = arr.length; a < l; ++a)
     var b = arr[a] + 1;
});
var times = benches.map( function(a) {
                      arr = new Array(11111111).fill(255);
                      return [a[0], bench(...a)]
                     }).sort( (a,b) => a[1]-b[1] );
var max = times[times.length-1][1];
times = times.map( a => {a[2] = (a[1]/max)*100; return a; } );
var template = (title, time, n) =>
  `<div>` +
    `<span>${title} &nbsp;</span>` +
    `<span style="width:${3+n/2}%">&nbsp;${Number(time.toFixed(3))}msec</span>` +
  `</div>`;

var strRes = times.map( t => template(...t) ).join("\n") + 
            `<br><br>for-loop without 'var' ${globalVarTime} msec.`;
var $container = document.getElementById("container");
$container.innerHTML = strRes;
body { color:#fff; background:#333; font-family:helvetica; }
body > div > div {  clear:both   }
body > div > div > span {
  float:left;
  width:43%;
  margin:3px 0;
  text-align:right;
}
body > div > div > span:nth-child(2) {
  text-align:left;
  background:darkorange;
  animation:showup .37s .111s;
  -webkit-animation:showup .37s .111s;
}
@keyframes showup { from { width:0; } }
@-webkit-keyframes showup { from { width:0; } }
<div id="container"> </div>


3
@Maykonnはおそらく「それはOpera Miniを
除い

3
@Maykonnすべてのユーザーの0.18%がIE8を使用しており、それをサポートするために時間を浪費してはならないため、デフォルトビューにはリストされていません。2018年は死んだ馬です。
デューブ2018

1
世界中のすべてのユーザーを考慮すると、それは間違いなく真実です。しかし、残念ながら、世界の特定の地域ではIE8がまだ関連しています。
Maykonn

1
可能であれば、異なるブラウザーでは異なるメソッドで異なる結果が得られるだけでなく、同じブラウザーでも異なる入力で異なる結果が得られます。巨大な数値のみの配列は非常に最適化されますが、小さな混合配列は最適化されません。
海洋堂

1
@ Tahlilありがとう。
nullqube

19

2014 Whileが帰ってきた

論理的に考えてください。

これ見て

for( var index = 0 , length = array.length ; index < length ; index++ ) {

 //do stuff

}
  1. 少なくとも2つの変数(インデックス、長さ)を作成する必要があります
  2. インデックスが長さより小さいかどうかを確認する必要があります
  3. インデックスを増やす必要がある
  4. forループは、3つのパラメータを持っています

これがなぜこれより速いのかを教えてください:

var length = array.length;

while( --length ) { //or length--

 //do stuff

}
  1. 1つの変数
  2. チェックなし
  3. インデックスが減少する(マシンはそれを好む)
  4. while パラメータは1つだけです

Chrome 28がforループがwhileよりも速いことを示したとき、私は完全に混乱しました。これはある種のことを引き起こしたに違いない

「ええと、誰もがforループを使用しているので、Chrome向けに開発するときはそれに焦点を当てましょう。」

しかし、現在、2014年には、whileループがChromeに戻りました。2倍高速です。他の/古いブラウザでは常に高速でした。

最近、私はいくつかの新しいテストを行いました。現実の世界では、これらの短いコードは何の価値もなく、jsperfは実際にはwhileループを適切に実行できません。

jsperfでwhileループの実際の速度を取得することはできません。

独自のカスタム関数を作成し、それを確認する必要があります window.performance.now()

ええと... whileループが単純に高速になる方法はありません。

本当の問題は、実際にはdom操作/レンダリング時間/描画時間であるか、それともあなたがそれを呼び出したいかです。

たとえば、私は座標と衝突を計算する必要があるキャンバスシーンを持っています...これは10〜200マイクロ秒(ミリ秒ではない)の間で行われます。すべてをレンダリングするのに実際には数ミリ秒かかります。DOMと同じです。

だが

forを使用する別の優れた方法がありloopます。たとえば、アレイをコピー/クローンする場合などです。

for(
 var i = array.length ;
 i > 0 ;
 arrayCopy[ --i ] = array[ i ] // doing stuff
);

パラメータの設定に注意してください。

  1. whileループと同じですが、変数を1つだけ使用しています
  2. インデックスが0より大きいかどうかを確認する必要があります。
  3. ご覧のとおり、この方法は3番目のパラメーター内で処理を行い、配列内で直接減少するため、誰もが使用する通常のforループとは異なります。

つまり、これは、次のようなマシンが

それを少し短くして無駄なものを削除することを考えていて、同じスタイルを使用してこれを書いたことを書いています:

for(
 var i = array.length ;
 i-- ;
 arrayCopy[ i ] = array[ i ] // doing stuff
);

それが短くても、iもう一度使用するとすべてが遅くなるように見えます。前のforループやwhile1 つよりも1/5遅いです。

注意:;なしloooのための後に非常に重要です{}

jsperfはスクリプトをテストするための最良の方法ではないと言っただけでも、ここにこの2つのループを追加しました

http://jsperf.com/caching-array-length/40

そして、これはJavaScriptのパフォーマンスに関する別の答えです

https://stackoverflow.com/a/21353032/2450730

この答えは、JavaScriptを作成するパフォーマンスの高い方法を示すことです。したがって、それを読むことができない場合は、質問すると、答えが得られるか、javascript http://www.ecma-international.org/ecma-262/5.1/に関する本が読まれます。


この答えは非常に良いものから始まります。過去2年間の方forがよりも高速であることに気づきました。while私が一度crome-devで読んだのは、あなたが言及した理由によるものでした。while再び追いつくのは時間の問題です。その時点から、あなたの回答の最初の部分のロジックが保持されます(もう一度、そうです)。ただし、現代の実装では、ecmaで指定されたすべての手順を厳密に実行することはありません(最適化)。これであなたのエンジンは最も目立ったボトルネックではなくなったので、逆ループでのCPUキャッシュミスに実際に気づくことができます
GitaarLAB 2015年

説明してください。多分私は答えを修正したり、何か新しいことを学んだりできます。ところで、答えは1年以上前です...ブラウザーは常にそうであるように、時間の経過とともに変化している可能性があります...
cocco

私の意見では、while(--length)は悪です。なぜなら、技術的には0がfalseであるため機能しますが、0とfalseは、意味的に言えば本当に同じものではないからです。
scott.korin

ええ...それは今では古い投稿です...しかし、ええ、私はそのシンプルさが大好きです。そして、どちらの場合もあなたが言及するように、何を書くべきかを知る必要があります。反対側では、負の数値をループする必要がありませんでした。
cocco

9
「機械はこれを好む」とは、洗濯洗剤の広告の文のように聞こえる
CocoaBean

11

http://jsperf.com/caching-array-length/60

私が準備した(古いものを再利用して)テストの最新リビジョンは、1つのことを示しています。

キャッシュの長さはそれほど重要ではありませんが、害はありません。

上記のリンク(新しく開いたタブで)の最初の実行ごとに、Debian Squeeze 64ビット(私のデスクトップハードウェア)のChrome、Opera、Firefoxの最後の4つのスニペット(チャートの3番目、5番目、7番目、10番目)の最良の結果が得られます)。その後の実行では、まったく異なる結果が得られます。

パフォーマンスに関する結論は簡単です。

  • forループ(フォワード)を使用して、の!==代わりにを使用してテストします<
  • 後で配列を再利用する必要がない場合は、減少した長さのループと破壊shift()的な配列の配列も効率的です。

tl; dr

最近(2011.10)のパターンは、最速のようです。

for (var i = 0, len = arr.length; i !== len; i++) {
    ...
}

arr.lengthここではキャッシングは重要ではないので、テストするだけi !== arr.lengthでパフォーマンスは低下しませんが、コードは短くなります。


PS:shift()その結果のスニペットで0番目の要素にアクセスする代わりに使用できることは知っていますが、以前のリビジョン(whileループが間違っていた)を再利用した後、どういうわけか見落とし、後で既に取得した結果を失いたくありませんでした。


let current = arr [i]のようなループ内で変数を作成すると、パフォーマンスが低下する可能性があります(大きなメモリ割り当て)?または、ループの前に電流を宣言する方が良いでしょうか?または、ループ内のすべての場所でarr [i]を使用しますか?
マカロフセルゲイ

8

純粋なパフォーマンスのように「最高」?またはパフォーマンス読みやすさ?

純粋なパフォーマンス「最高」はこれであり、キャッシュと++ prefix演算子を使用します(私のデータ:http : //jsperf.com/caching-array-length/189

for (var i = 0, len = myArray.length; i < len; ++i) {
  // blah blah
}

キャッシュレスのforループは、実行時間とプログラマーの読み取り時間の最適なバランスであると私は主張します。C / C ++ / Javaで始めたすべてのプログラマーは、これを読むためにmsを無駄にすることはありません。

for(var i=0; i < arr.length; i++){
  // blah blah
}

2
読みやすくするために+1。どれだけ適切なlen名前が付けられていても、最初のループで常にダブルテイクを行う必要があります。2番目のループの意図は明白です。
Josh Johnson

7

**配列内の長さをループ内にキャッシュします。数秒の時間を回避できます。配列の項目が多い場合、配列の項目に依存します。時間のMsに関して大きな違いがあります*

**

sArr; //Array[158];

for(var i = 0 ; i <sArr.length ; i++) {
 callArray(sArr[i]); //function call
}

***end: 6.875ms***

**

**

sArr; //Array[158];
for(var i = 0,len = sArr.length ; i < len ; i++) {
  callArray(sArr[i]); //function call
}

***end: 1.354ms***

**


6

これ断然最速の方法のようです...

var el;
while (el = arr.shift()) {
  el *= 2;
}

これがアレイを消費し、それを食べ、何も残っていないことを考慮に入れてください...


2
arr.shift();代わりにarr.pop() 、配列の逆転を回避できます。
Tintu C Raju 2015

1
@Gargaroz(チャットサービスや製品カタログのアイテムなどのWebサービスからJSONを取得する場合)。配列を1回だけ使用する必要がある場合の別の状況としては、たとえば、間隔ごとに多くの座標を取得するチャートがあります。多くの例があります。
セルジオ

クール、説明ありがとうございます。この種類のループを悪用するためのさらなる例を見つけることができる方向に私を向けることができますか?
Gargaroz、2016

1
現在Chrome 53とFirefox 48でこれは最も遅いアプローチの1つです-perfjs.info/array-iterationを
Pencroff

1
@Alirezaも同意します。私の回答にもそのコメントがあります。
セルジオ

4

それは年だ2017

私はいくつかのテストを行いました。

https://jsperf.com/fastest-way-to-iterate-through-an-array/

このwhile方法はChromeで最速のようです。

左デクリメントのように見えますが(--i)はるかに高速に他の(より++ii--i++Firefoxの上)。

このアプローチは、平均して断食です。ただし、逆の順序で配列を反復処理します。

let i = array.length;
while (--i >= 0) {
    doSomething(array[i]);
}

順方向が重要な場合は、このアプローチを使用してください。

let ii = array.length;
let i = 0;
while (i < ii) {
    doSomething(array[i]);
    ++i;
}

3
キーワードletを使用することにより、実際にはループパフォーマンスではなくスコープ作成パフォーマンスを比較します。ループで使用すると、ブロック内にこれらの変数の新しいスコープが作成さlet i = 0, ii = array.lengthれます。あなたの例はブロック内の変数のための新しいスコープを作成しません、そしてそれがそれらがより速い理由です。forループの代わりにを使用すると、2017年のforループがいかに高速であるかがわかりますが、より読みやすくなっています。forforwhilewhilevarlet
CGodo

これが私が話しているjsperf
CGodo

これはChromeのみの問題です。他のブラウザでvarlet同じ性能持っている- stackoverflow.com/a/32345435/1785975
SeregPie

面白い。とにかく、「whileChromeの方が速い」という記述は正確ではありません。letChromeでのそのキーワードのパフォーマンスの問題のために使用する場合のみです。使用している場合varや他のブラウザでは、forwhileほとんど同じですが、時々forベンチマークに依存しても高速であり、そしてそれは、よりコンパクトで読みやすい私見です。
CGodo 2017年

2

私はいつも最初のスタイルで書いています。

コンパイラーが配列用に最適化できるほどスマートでも、ここでDOMNodeListまたは計算された長さを持ついくつかの複雑なオブジェクトを使用している場合でも、スマートですか?

配列についての質問は知っていますが、すべてのループを1つのスタイルで記述することをお勧めします。


1
var arr = []; // The array
var i = 0;
while (i < arr.length) {
    // Do something with arr[i]
    i++;
}

i ++は++ i、-iおよびi--より高速です。

また、最後にiにアクセスする必要があるときに、arr [i ++]を実行する最後の行を保存できます(ただし、これはデバッグが難しい場合があります)。

ここでテストできます(他のループテストを使用):http : //jsperf.com/for-vs-whilepop/5


1
現在Chrome 53でそれは本当ですが、Firefox 48は同じ速度です-perfjs.info/array-iterationを
Pencroff


1

2017年9月現在、これらのjsperfテストは、Chrome 60で最もパフォーマンスが高い次のパターンを示しています。

function foo(x) {
 x;
};
arr.forEach(foo);

誰かが再現できますか?


はい、それは最も速いようですが、IE11でこれを実行してみてください、そしてそれらのオプションは最も遅いです。また、Firefox 55.03では、「古いバストキャッシュされたlen」が12milになり、3.3kのChromeと比べて驚異的なパフォーマンスを実現しています。すべてのブラウザでパフォーマンスの一貫性を保つには、すべてのブラウザで最速の平均ループを使用する必要があります。
Plippie 2017年

0

巨大な配列を反復処理する他の方法を試してみましたが、配列の長さを半分にしてから、両方の半分を1つのループで反復する方が高速であることがわかりました。このパフォーマンスの違いは、巨大な配列を処理しているときに確認できます

var firstHalfLen =0;
var secondHalfLen = 0;
var count2=0;
var searchterm = "face";
var halfLen = arrayLength/2;
if(arrayLength%2==halfLen)
{
   firstHalfLen = Math.ceil(halfLen);
   secondHalfLen=Math.floor(halfLen);
}
else
{
   firstHalfLen=halfLen;
   secondHalfLen=halfLen;
}
for(var firstHalfCOunter=0,secondHalfCounter = arrayLength-secondHalfLen;
    firstHalfCOunter < firstHalfLen;
    firstHalfCOunter++)
{
  if(mainArray[firstHalfCOunter].search(new RegExp(searchterm, "i"))> -1)
  {
    count2+=1;
  }
  if(secondHalfCounter < arrayLength)
  {
    if(mainArray[secondHalfCounter].search(new RegExp(searchterm, "i"))> -1)
    {
        count2+=1;
    }
    secondHalfCounter++; 
  }
}

キャッシュされた長さのforループと上記の方法のパフォーマンス比較(timer.jsを使用)。

http://jsfiddle.net/tejzpr/bbLgzxgo/


0

別のjsperf.comテスト:http ://jsperf.com/while-reverse-vs-for-cached-length

逆のwhileループが最も速いようです。唯一の問題は、(-i)が0で停止することです。その場合、ループでarray [0]にどのようにアクセスできますか?


2
その場合はwhile (i--)、その後の真実性はiデクリメントではなく、デクリメントして、真実をテストする前にテストされます。
Justin Fisher、


0

whileループはforループよりも少し高速です。

var len = arr.length;
while (len--) {
    // blah blah
}

代わりにwhileループを使用してください



-1

私が知っている最もエレガントなソリューションはマップを使用することです。

var arr = [1,2,3];
arr.map(function(input){console.log(input);});

46
質問は、ループを反復処理する最も遅い道を求めていません
eoleary

-1

これを試して:

var myarray =[],
i = myarray.lenght;
while(i--){
// do somthing
}

-1

配列をループする最も速い方法は、フィルターを使用することです。filter()メソッドは、提供された関数によって実装されたテストに合格したすべての要素を含む新しい配列を作成します。

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter

const words = ['Floccinaucinihilipilification', 'limit', 'elite', 'Hippopotomonstrosesquipedaliophobia', 'destruction', 'present'];

const result = words.filter(word => word.length > 6);

console.log(new Date(), result);

私の経験から、私は常にフィルター、マップなどを好みます。


問題は、アレイを新しいアレイにコピーしないで、最短時間でアレイを反復することです。
Rahul Kadukar、

-1

2019年以降、WebWorkerの人気が高まりました。大規模なデータセットの場合、マルチコアプロセッサを完全に利用することで、WebWorkerを使用してはるかに高速に処理できます。

また、Parallel.jsを使用して、WebWorkerをデータ処理ではるかに使いやすくします。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.