What's the fastest way to loop through an arra

2019-01-01 07:58发布

I learned from books that you should write for loop like this:

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

so the arr.length will not be calculated each time.

Others say that the compiler will do some optimization to this, so you can just write:

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

I just want to know which is the best way in practice?

21条回答
低头抚发
2楼-- · 2019-01-01 08:42

This looks to be the fastest way by far...

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

Take into account that this will consume the array, eating it, and leaving nothing left...

查看更多
明月照影归
3楼-- · 2019-01-01 08:42

I'm always write in the first style.

Even if a compiler is smart enough to optimize it for arrays, but still it smart if we are using DOMNodeList here or some complicated object with calculated length?

I know what the question is about arrays, but i think it is a good practice to write all your loops in one style.

查看更多
低头抚发
4楼-- · 2019-01-01 08:44

2014 While is back

Just think logical.

Look at this

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

 //do stuff

}
  1. Need to create at least 2 variables (index,length)
  2. Need to check if the index is smaller than the length
  3. Need to increase the index
  4. the for loop has 3 parameters

Now tell me why this should be faster than:

var length = array.length;

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

 //do stuff

}
  1. One variable
  2. No checks
  3. the index is decreased (Machines prefer that)
  4. while has only one parameter

I was totally confused when Chrome 28 showed that the for loop is faster than the while. This must have ben some sort of

"Uh, everyone is using the for loop, let's focus on that when developing for chrome."

But now, in 2014 the while loop is back on chrome. it's 2 times faster , on other/older browsers it was always faster.

Lately i made some new tests. Now in real world envoirement those short codes are worth nothing and jsperf can't actually execute properly the while loop, because it needs to recreate the array.length which also takes time.

you CAN'T get the actual speed of a while loop on jsperf.

you need to create your own custom function and check that with window.performance.now()

And yeah... there is no way the while loop is simply faster.

The real problem is actually the dom manipulation / rendering time / drawing time or however you wanna call it.

For example i have a canvas scene where i need to calculate the coordinates and collisions... this is done between 10-200 MicroSeconds (not milliseconds). it actually takes various milliseconds to render everything.Same as in DOM.

BUT

There is another super performant way using the for loop in some cases... for example to copy/clone an array

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

Notice the setup of the parameters:

  1. Same as in the while loop i'm using only one variable
  2. Need to check if the index is bigger than 0;
  3. As you can see this approach is different vs the normal for loop everyone uses, as i do stuff inside the 3th parameter and i also decrease directly inside the array.

Said that, this confirms that machines like the --

writing that i was thinking to make it a little shorter and remove some useless stuff and wrote this one using the same style:

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

Even if it's shorter it looks like using i one more time slows down everything. It's 1/5 slower than the previous for loop and the while one.

Note: the ; is very important after the for looo without {}

Even if i just told you that jsperf is not the best way to test scripts .. i added this 2 loops here

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

And here is another answer about performance in javascript

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

This answer is to show performant ways of writing javascript. So if you can't read that, ask and you will get an answer or read a book about javascript http://www.ecma-international.org/ecma-262/5.1/

查看更多
旧时光的记忆
5楼-- · 2019-01-01 08:45

As of September 2017 these jsperf tests are showing the following pattern to be most performant on Chrome 60:

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

Is anyone able to reproduce?

查看更多
弹指情弦暗扣
6楼-- · 2019-01-01 08:45

**cache the array length inside the loop ,some seconds of time will be eluded . Depends on the items in the array if there are more items in array there is major difference with respect to Ms of time*

**

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***

**

查看更多
几人难应
7楼-- · 2019-01-01 08:45

It's the year 2017.

I made some tests.

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

Looks like the while method is the fastest on Chrome.

Looks like the left decrement (--i) is much faster than the others (++i, i--, i++) on Firefox.

This approach is the fasted on average. But it iterates the array in reversed order.

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

If the forward order is important, use this approach.

let ii = array.length;
let i = 0;
while (i < ii) {
    doSomething(array[i]);
    ++i;
}
查看更多
登录 后发表回答