PDA

View Full Version : A Better While Loop


Rhuno
05-12-2011, 01:22 AM
Hey all,

At work this past week I was looking over some code in the new project I'm on. It was using a lot of while loops and after looking at it for a bit, an idea popped into my head and I thought I'd give it a shot - it worked, and wonderfully so.

The big problem with while loops is that it's easy to forget to increment your counter which of course leads to an infinite loop and a dead program. I have since started incrementing the counter in the while statement itself. It's a super simple change and an easy habit to pick up. Best of all? No more infinite loops because of a forgotten increment statement.

Below is a standard while loop - nearly every loop I've seen in 8 years of development has been written this way.


var count:int = 0;
while(count < 1000)
{
// do stuff
count++;
}


And here is the way I've started writing my while loops:


var count:int = -1;
while(++count < 1000)
{
// do stuff
}


I was just curious if anyone here uses that same style or if you've always used the more "traditional" structure?

Thoughts and comments are welcome.

tadster
05-13-2011, 10:28 AM
Makes sense, but then you have to remember to start from -1.
But I think it looks cleaner.

SDragon029
05-15-2011, 05:39 PM
Hey that's actually a really good idea. I never thought of writing my while loops like that. I was always taught to do them the more traditional way by at least 3 different professors in my schooling years.

poltuda
05-16-2011, 08:17 AM
To get the same result:

var count:int=0;
while (count<1000) {
trace("while 1="+count);
count++;
}
while (count++<1000) {/*++count<1000*/
trace("while 2="+(count-1));
}




poltuda

tadster
05-30-2011, 12:27 AM
It's showing the count.


trace("while 1="+count);// "while 1 = 0" - (and on each iteration 0 increases by 1)

trace("while 2="+(count-1));// "while 2 = 0" - (ditto)


I think Poltuda put the 1 and 2 to denote which style of loop it is... you know, using the word while as a noun in that sense, while version #1 and #2.



Thanks for showing that Poltuda.

edit: hmmm.... there was another post after poltudas where someone asked what the trace statements were doing... that's what I was answering.. I guess that person deleted their reply.

josh_ak
07-08-2011, 09:24 PM
This may be a really dumb question (I am not a seasoned programmer) and it is probably off point slightly, but why not use a "for" loop instead if you are just incrementing a counter. It has an explicit increment parameter (whats to stop you from forgetting to increment in your while statement?) . The syntax of a "for" loop is similar to your improved code, and wouldn't make me pause and think at that line if I was reading it.


var count:int = 0
for(count; count <1000; count++){
// do stuff
}


If I am thinking about it correctly, the "while" loop really gains you the ability to conditionally continue based on something other than simple a counter, but your improved method is limited to only using it with a counter.

Again, I am not trying to Flame or be critical. You probably have much more experience than me, so I would love to hear your opinion.

Thanks,

Josh

audiopro
07-11-2011, 06:33 PM
Traditionally, for/next loops were used when something had to be repeated a set number of times and while loops were used when waiting for an external event to occur.

ASWC
07-11-2011, 07:15 PM
He's showing this because while loop are known to be a bit faster than for loop in AS3. So then a bunch of coder dropped altogether for loops and started like he did using only while loops for everything. For everything that is meant to run a certain amount of time I use for loop and for everything that is meant to run until a condition is meet I use while loop. I don't write 3D application with thousands of vertices to deal with so no need to bother. (and most of those while loop only coder don't either)

josh_ak
07-11-2011, 09:19 PM
@ASWC: I went looking at optimization tips after your post and wow was that enlightening. I have always focused on readability and only looked at optimization when something performed sub par. I know that optimization is probably one of those things that people argue about, but all the pages I found said that for loops were lightly better or the same as while loops. One post (http://www.actionscript.org/forums/showthread.php3?t=50255) said that the compiled code is the same in a simple example.

@Rhuno: I also noticed that in one of Adobe's optimization (http://help.adobe.com/en_US/as3/mobile/WS4bebcd66a74275c3a0f5f19124318fc87b-7ffc.html) examples they use exactly your style (not as a recommended optimization, but rather just how they wrote the example).

Rhuno
07-28-2011, 08:50 PM
I didn't really do it as a performance optimization, but more of as a safety measure against infinite loops because I often times forget to increment counters in while loops. I was just curious to see if anyone else wrote while loops this way because I hadn't encountered it before; cool to see the sample in Adobe documentation.

I should also point out: I definitely do NOT use while loops for everything. :)

inhan
08-02-2011, 08:35 PM
I was going to start a thread and I saw this one. Good point. Today I was trying a couple of differently constructed loops to see which performs faster. Here is my script and the results by my processor:

var var1:int = 0;
// new values get assigned in this
// variable by the loops.
var startTime:uint;
var loopCount:int = 1000000;
// yes, this is a million
var i:int = 0;

function withForLoop1A():void {
startTime = getTimer();
for (i = 0; i < loopCount; i++) {
var1 = i;
}
trace("For loop 1A took", getTimer() - startTime, "ms.");
}
function withForLoop1B():void {
startTime = getTimer();
for (i = 0; i < loopCount; i+=1) { // i += 1 rather than i++
var1 = i;
}
trace("For loop 1B took", getTimer() - startTime, "ms.");
}
function withWhileLoop1A():void {
i = 0;
startTime = getTimer();
while (i < loopCount) {
var1 = i;
i++;
}
trace("While loop 1A took", getTimer() - startTime, "ms.");
}
function withWhileLoop1B():void {
i = 0;
startTime = getTimer();
while (i < loopCount) {
var1 = i;
i += 1; // rather than i++
}
trace("While loop 1B took", getTimer() - startTime, "ms.");
}
function withWhileLoop2():void {
var j:int = -1;
startTime = getTimer();
while (++j < loopCount) { // pre-increment
var1 = j;
}
trace("While loop 2 took", getTimer() - startTime, "ms.");
}

withForLoop1A(); // 15-19 ms.
withForLoop1B(); // 11-12 ms.
withWhileLoop1A(); // 14-17 ms.
withWhileLoop1B(); // 10-12 ms.
withWhileLoop2(); // 8-10 ms.