63

Given this code:

var arr = [];

for (var i = 0; i < 10000; ++i)
    arr.push(1);

Forwards

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

Backwards

for (var i = arr.length - 1; i >= 0; --i) {}

Hard-coded Forward

for (var i = 0; i < 10000; ++i) {}

Why is backwards so much faster?

Here is the test: https://jsperf.app/array-iteration-direction

3

7 Answers 7

90

Because your forwards-condition has to receive the length property of your array each time, whilst the other condition only has to check for "greater then zero", a very fast task.

When your array length doesn't change during the loop, and you really look at ns-perfomance, you can use

for (var i=0, l=arr.length; i<l; i++)

BTW: Instead of for (var i = arr.length; i > 0; --i) you might use for (var i = arr.length; i-- > 0; ) which really runs through your array from n-1 to 0, not from n to 1.

Sign up to request clarification or add additional context in comments.

12 Comments

Yep, this is how I do it for optimized functions. Just note that if the array is mutable (and it usually isn't), this may skip a resource or two. For example, this won't work if you're looping through elements that the loop itself is adding or deleting.
you can even do for(... ; i-- ;)
so basically it means that if I don't change the array and I keep array.length in a variable, then backwards speed = forward speed? Example: var length = array.length; for(var i = 0 ; i<length ; i++);
afaik, i<l is a different computation than i>0, but yes they're rather equal (faster than uncached length): jsperf.com/array-iteration-direction/3 - yet some engines do recognize and optimize some of these cases
Fast forward to 2018. it looks like the modern versions of browsers don't make loop slower even when accessing arr.length in each iteration (your forwards case)
|
9

Because in the first form you are accessing the property length of the array arr once for every iteration, whereas in the second you only do it once.

2 Comments

@samccone - what result are you seeing (which test in which browser)? I'm seeing that caching the length is always at least as fast and usually faster.
alright you are correct... it looks like it is really a mixed bag of results tho but caching does help it... thanks XD
7

If you want to have them at same pace, you can do that for forward iteration;

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

So, your script won't need to take length of array on everystep.

1 Comment

Ahhh... interesting your method now takes the crown for fastest iteration jsperf.com/array-iteration-direction
5

I am not entirely sure about this, but here is my guess:

For the following code:

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

During runtime, there is an arr.length calculation after each loop pass. This may be a trivial operation when it stands alone, but may have an impact when it comes to multiple/huge arrays. Can you try the following:

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

In the above code, we compute the array length just once, and operate with that computed number, rather than performing the length computation over and over again.

Again, just putting my thoughts out here. Interesting observation indeed!

Comments

3

i > 0 is faster than i < arr.length and is occurring on each iteration of the loop.

You can mitigate the difference with this:

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

This is still not as fast as the backwards item, but faster than your forward option.

1 Comment

look at the hard coded test jsperf.com/array-iteration-direction ... using your logic it should be faster no?
2

do it like below, it will perform in same way. because arr.length takes time in each iteration in forward.

int len = arr.length;

forward

for (var i = 0; i < len; ++i) {
}

backward

for (var i = len; i > 0; --i) {
}

2 Comments

The backward case isn't right. What I do is for(i=len; --i>=0;){
for (let i = arr.length; i-- > 0;) {
2

And these are equally good:

var arr= [], L= 10000;
while(L>-1) arr[L]= L--;

OR

var arr= [], i= 0;
while(i<10001) arr[i]=i++;

1 Comment

It should be while(--L>=0) arr[L] = L;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.