Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Array.length in a for loop

New Here ,
Jul 27, 2011 Jul 27, 2011

Okay here is the debate. I like to use array.length in my for loop to keep my code cleaner to read. Is there any huge downside to this? For example will it speed up things greatly if i store the length in a var one time?

Thanks for any insight!!

TOPICS
ActionScript
3.2K
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

LEGEND , Jul 27, 2011 Jul 27, 2011

Math speaks for itself.

Using variable instead of length is more than 20 times faster. So, conclusion, undoubtedly, is that setting variable to array length and then using it in a loop is the way to go, especially on large iterations.

Here is a benchmark test:

Without length:

var st:Number = getTimer();
for (var i:int = 0; i < 1000000; i++ ) {     
}
trace(getTimer() - st);

Trace returns something around 12 ms

With array length:

var array:Array = [];
for (var j:int = 0; j < 1000000; j++)
{
     array.push(1)

...
Translate
Participant ,
Jul 27, 2011 Jul 27, 2011

Feel free to use array.length, there's no benefit to storing it in a different variable. In fact, it's better to use array.length, taking into account that your code will be more readable, and you have one less variable. Just make sure you don't change the length of the array in the loop (that would be bad practice anyway.)

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 27, 2011 Jul 27, 2011

Having the added weight of another variable might have a greater impact than looking at the array for a property  One downside I see goes the other way... what if the array changes... what extra code do you need to have that variable keep tracking the changing length.  I'd stick with the array.length.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jul 27, 2011 Jul 27, 2011

That's my thinking exactly. Can any Adobe employees confirm that this is the best approach?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 27, 2011 Jul 27, 2011

It's doubtful you'll find any Adobe employees around here to confirm anything.  Adobe employees don't use these user-to-user forums as a general rule.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jul 27, 2011 Jul 27, 2011

Ahhh thanks Ned!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 27, 2011 Jul 27, 2011

Math speaks for itself.

Using variable instead of length is more than 20 times faster. So, conclusion, undoubtedly, is that setting variable to array length and then using it in a loop is the way to go, especially on large iterations.

Here is a benchmark test:

Without length:

var st:Number = getTimer();
for (var i:int = 0; i < 1000000; i++ ) {     
}
trace(getTimer() - st);

Trace returns something around 12 ms

With array length:

var array:Array = [];
for (var j:int = 0; j < 1000000; j++)
{
     array.push(1);
}
var st:Number = getTimer();
for (var i:int = 0; i < array.length; i++)
{
     
}
trace(getTimer() - st);

Trace returns about 220-224 ms

This is a clear confirmation of what to use.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Jul 28, 2011 Jul 28, 2011

If you use Array.length as for loop condition Flash has to evaluate Array.length on each iteration again and again. This is slow, waste of resource, and not elegant There are no difference in the code "readability" here so there are no reasons you should use inefficient method specifically.

Using Andrei's example (but with a larger number):

var array:Array = [];
for (var i:uint = 0; i < 9000000; i++) {
     array.push(1);
}

var st:uint;

st = getTimer();
for (var j:uint = 0; j < array.length; j++) {
     // loop 1
}
trace("loop 1", getTimer() - st);

st = getTimer();
var len:uint = array.length
for (var k:uint = 0; k < len; k++) {
     // loop 2
}
trace("loop 2", getTimer() - st);

// trace
// loop 1 682
// loop 2 112

If you store the length in a var it's much faster.

How I usually do is to create a var to store the length in the for loop initialisation so the code is cleaner:

st = getTimer();
for (var l:uint = 0, len2:uint = array.length; l < len2; l++) {
     // loop 3
}
trace("loop 3", getTimer() - st);

// trace
// loop 3 111

The speed is the same as the loop above.

You can also assign the length to the iterater at the initialisation, then subtract 1 on each iteration:

st = getTimer();
for(var m:uint = array.length - 1; m > 0; --m){
    // loop 4
}
trace("loop 4", getTimer() - st);

// trace

// loop 4 118

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jul 28, 2011 Jul 28, 2011

Unfortunately, this issue is exacerbated logarithmically when you nest

loops. I did a getTimer() style test with nested loops over two small

arrays (100 elements) and saw a 95% performance difference. 95%!!!!

There are lots of AS optimization techniques that actually do make

code less readable, this isn't one of them. Bitwise shifting is far

more performant than the Math class, for example, but far harder to

read. If you draw an arbitrary 'readability' line with this technique,

how will you ever let yourself take advantage of more advanced

techniques?

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 28, 2011 Jul 28, 2011

Ken,

I love the brevity and elegance of your loop initialization techniques. Thank you!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jul 28, 2011 Jul 28, 2011

Thanks everyone for your efforts!

I've made the switch to Ken's approach. I think that's most in line with what I was looking for in removing the initial var.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jul 29, 2011 Jul 29, 2011
LATEST

Yeah - Ken's initialization approach absolutely introduces the length optimization benefit for a single flat loop. The only 'gotcha' that I see would be with nested loops. A nested loop structure, which is a far more delicate creature - requiring extra special care, will not benefit from this optimization if you set the inner loop's length var in the initializer of the inner loop. The nested loop code block will only benefit from this optimization if you set the inner loop's length var in the outer loop's initializer or before the outer loop starts.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 27, 2011 Jul 27, 2011

And even without benchmark testing, it is just logical that using preset variable instead of Array.length must be faster. Array.length is a property that resides in a different scope - this is already slower to read its value from a different scope (while declared variable is residing in the same scope). in addition, length is NOT A PURE PROPERTY but an accessor (setter/getter). Thus, because methods are inherently slower than properties - it makes it even slower to read length.

In a loop on EVERY ITERATION length is read afresh - it is not indexed. Hence, obviously, using a distinct variable is more efficient.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jul 27, 2011 Jul 27, 2011

Thanks for the tests!

That said, this is with a million objects in the array. I have under 350. Also, @ 1,000 items in the array they both don't calculate to a millisecond (ie 0 vs 0). At 10,000 items it is it's mixed between 0 vs 1 and sometimes 0 vs 2. If it's a matter of 2 milliseconds I'll take more readable code all day long.

Thanks everyone for you help on this! For large iterations it's definetly more valuable to use a scoped var.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 27, 2011 Jul 27, 2011

Well, I strongly believe (which is confirmed by experience) that choosing code readability over performance is an EXTREMELY bad idea and quite a deviation from best OOP practices. I would NEVER EVER take readable code over performance. I hope you realize it sooner than later.

Milliseconds and microseconds pile up very quickly. Remember that average 30 frame per second rate gives you only 33 milliseconds to process code. IN EVERY SCOPE.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jul 27, 2011 Jul 27, 2011

While I apprieciate your kind words you're failing to recognise that my use case didn't render a difference. Also, I'm sure that you are of great experience but I think you can benifit from improving how you interact with people. This was meant to be a friendly discussion where I was hoping to get opinions from experts like yourself; save the caps lock for angry IM's with your counterpart.

Thanks everyone for your insight!!!!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jul 27, 2011 Jul 27, 2011

I'm going to have to disagree with Andrei1 - You're right ryancanulla that in your case, it's an insignificant difference in performance, and his numbers are very bloated by an unrealistic situation (ahh, statistics, how malleable).

Also, readability is HUGE - when it comes to speed, and *especially* memory, for the kinds of applications that will be created in AS3 it is WELL worth making small (imperceptible) performance sacrifices to make code more readable. ANY software engineer worth his salt can give you an earful about the importance of organized and readable code. While yes, in some systems you want to eke all the performance you can, creating a flash app is NOT one such system.

Just backing you up ryancanulla, you made the right call

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 27, 2011 Jul 27, 2011

Fehute,

I am sorry but what you are saying is odd and very unreasonable in my view. I think it is even dangerous for ones who strive to become well rounded programmers.

"his numbers are very bloated by an unrealistic situation (ahh, statistics, how malleable)"

This is skewed! Those are not MY numbers. My brain doesn't run on my laptop's CPU. These are the results of running of an application.

What is realistic? Can you fetch a number that signifies a clear demarcation between realistic/unrealistic and substantiate it?

Factor of 20 is just that - 20, no matter if it is expressed in milliseconds, nano-seconds or miles. How can it be possibly perceived as an ambiguous thing? After all, why even bother to deal with uncertainty when thing are so clear up to the last decimal? Life is so much easier when the fastest ways are implemented, is not it?

"ANY software engineer worth his salt can give you an earful about the importance of organized and readable code."

I guess this about those ubiquitous slackers that fill management positions in IT departments.

It is simply not true. Any software engineer that enforces readability over performance is a fake and should be demoted no matter how much pickle (salt) he absorbed. It just screams one thing - this kind of engineer doesn't give a dime and, most probably, is not a very professional/knowledgeable person (I hope I will never work with this kind of amateur being in a management position). After all, readability is for a mid level people who need hand handling. Seasoned developers can comprehend any code at a glance. This is not to mention that good code is the one where there is a thought/well defined reasoning behind every line - good, skilled developer can explain every bit of his code, including how this line affects performance (and application size). Why any serious software developer will ever be concerned with "code readability"? Code commenting is something I will agree with.

"While yes, in some systems you want to eek all the performance you can, creating a flash app is NOT one such system."

Why not, may I ask? What is wrong with high quality?

As a matter of fact this kind of paradigm (especially when it is perceived it as instructive) creates a bad reputation for Flash. Of course, no one has to feel responsible for the fact that all this sh** people develop in Flash is instrumental to one of the biggest obstacles Flash technology, unfortunately, has encountered. Namely - resistance from mobile device implementation, most notably iOS.

There is no questioning in my mind of the fact that the Devil is in details. A good news is that if there is a question - there is a huge room for growth.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Participant ,
Jul 28, 2011 Jul 28, 2011

Like ryancanulla said, just grow up and drop it.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jul 28, 2011 Jul 28, 2011

I think the readability Ryan is seeking is both subjective and insignificant when compared to the best practice of optimization that is backed up by objective data. Another benchmarking post on this exact topic supports the objective data:
http://blog.aidentailor.net/2010/02/03/actionscript-performance-loops/

Adding a local variable does not make the code less-readable, in fact, it makes it more readable.
It is more readable because the local var expresses the intent of optimization as a best practice.
If I were to come across that code, I would refactor it with a local var, as a matter of course, to improve the overall optimization and express to others that maintain that code that this is the best way to do it. Performance optimization is a cummulative art, and not following the best practices undermines that accumulation.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 28, 2011 Jul 28, 2011

Chris,

Thank you very much!

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Jul 27, 2011 Jul 27, 2011

I am sorry you misinterpreted my post as a manifestation of unfriendliness and anger, especially because your question, I feel, is a demonstration of a sharp thought process - there are very few people who dare to explore things at this depth. Frankly, this is the only reason I choose to type another post.

I used caps to stress important point because forum formatting features do not work properly. In any case, I have nothing to apologize for because, from the perspective of sharing AS3 knowledge, common sense is something that is difficult to argue against.

In addition, there are many more people who will read this thread. I hope the outcome is the best possible and other developers who read this thread will start taking into consideration that

1. often opinions expressed in this forum do not reflect realities of AS3 and Flash performance;

2. there is almost always a way to measure things in software and validate personal takes against actual core functionality;

3. finding the best possible approach pays off when performance bottleneck hits the fan;

4. statement like "I'll take more readable code all day long" are counterproductive (sorry - there is nothing personal, it is just, unfortunately, an illustration of all too common occurrence of assumption that corner cutting is benign).

"you're failing to recognise that my use case didn't render a difference."

The fact that there is no way to detect time smaller than 1 millisecond in AS3 doesn't mean performance doesn't deteriorate when less efficient approaches are employed. There is always something smaller unitl byte level is hit.

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Jul 27, 2011 Jul 27, 2011

"I'll take more readable code all day long (in this case)" -- edited

I can't tell if you are complimenting me or yourself in the first paragraph.

Listen, let's just end this to save the thread for future readers. I made an

attempt to gather reasonable information and base my own opinion, an opinion

I stand by. I suggest future readers do the same in formulating their

own...

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines