views:

163

answers:

8

If givin some situation that you can do a loop of a certain event or function that needed to be solved using loops, where you can achieve these by any kind of loop. How can we determine the difference between each loops that can be used based on their speed, efficiency, and memory usage? Like for example, you have these loops

for(int i=0;i<10;i++) {
    array[i] = i+1;
}

int i = 0;
while(i<10) {
    array[i] = i+1;
    i++;
}

The above example have the same output, of course you cannot see the difference between them when executed since this is just a small process, what if you are processing an enormous loop that's eating up your memory? Which loop is better to use? Is there a proper measure when to use what loop?

Edit:

for pakore answer,

From your answer I can safely say that If I reorder my variables where most of the variables that are dependent are far from each other (with other lines inbetween) could have been more efficient. Say for example,

a=0;
b=1;
c=5;
d=1;
for(int i=0; i<10;i++)
{
    a=b*CalculateAge()+d;
    m=c+GetAvarage(a);
    d++;
}

and

a=0;
b=1;
c=5;
d=1;
for(int i=0; i<10;i++)
{
    a=b*CalculateAge()+d;
    d++;
    m=c+GetAvarage(a);
}

The later is more efficient than the first one since in the later I have called an outside method on the first line and the second line is independent from the result of the first line than on the third line.

Since the first example will wait for the result of the first line before executing the second line and on the third, and the second example has already executed the second line while waiting for the result of the first line.

Conclusion:

An optimized loop doesn't mater what kind of loop you are using. As what pakore explained, and polygenelubricants, the main thing that you can mind in your loop is how your code is written inside. It is the compilers job to optimize your code, it also helps if you optimize your code according to its dependency with each variable as what pakore explain below.

A: 

the names of the loops themselves give an idea about the usage.

When you just have to perform an operation, no questions asked, a for loop does well.

In case you are iterating over the data structure and have a constraint, like a break condition or something like that, a while or do while loop should be chosen.

Kaustubh
A: 

Its just a matter of personal preference and coding style - the preferred style also depends a lot on the language you are coding in.

For example in python the preferred way to do the above loop looks a little like:

for i in range(0, 9):
    array[i] = i + 1

(In fact in Python you can do the above in a single line:

array = range(1,10)

But its just an example...)

Of the above two my preference would be with the first one.

As for performance, you are unlikely to see a difference.

Kragen
+2  A: 

I will explain each loop case one by one,

1.For loop: When you are sure that you do certain no of iterations then go for for loop.

2.While loop: When you are not sure of no of iterations then go for while loop or you want to loop through until the condition is false.

3.do-while:This is same as while loop except that loop is executed for atleast once.

Having said that , it is also ok to write one loop for another case.

4.Recursion: If you understand recursion correctly, recursion leads to elegant solutions. recursion is a bit slower than straight forward iteration.

There is no performance differences between for,while,do-while.If any,they are negligible.

Srinivas Reddy Thatiparthy
yes, this is actually what should we do, but I really want to know more deeper like much more on how the machine handle your code, just like pakore sited.
rob waminal
+7  A: 
pakore
I have edited my question to clarify what you have tried to explain here.
rob waminal
+1 for "My suggestion is that let the compiler take care about these things..."
atamanroman
I've replied to the updated part of your question.
pakore
sorry my bad, I am supposed to use `a` as the parameter for GetAverage()
rob waminal
A: 

It would surely depend on the language you are using, but remember that the slowest part of any code is the person coding it, so I would suggest pick a standard for each situation and stick with it, then when you come to update code you don't need to think about this each time.

If you are trying to make savings in ways such as this then you are either already running at near 100% efficiency or are perhaps looking in the wrong place to quicken up your code?

Toby
A: 

In the book "Computer organization and design: the hardware/software interface" of Patterson and Hennessy authors transform the loops above to assembly, and both loops have the same assembly code in MIPS.

Differences emerge if your compiler compiles both loops in different assembly statements if not they have same performance.

Novemberland
+1  A: 

Any decent compiler will generate the same code.

To test this I created a file named loops-f.c:

void f(int array[])
{
    for(int i=0; i<10; i++) {
        array[i] = i+1;
    }
}

and a file named loops-g.c:

void g(int array[])
{
    int i = 0;
    while(i<10) {
        array[i] = i+1;
        i++;
    }
}

I compiled the files to assembly (gcc -std=c99 -S loops-f.c loops-g.c) and then I compared the generated assembly code (diff -u loops-f.s loops-g.s):

--- loops-f.s   2010-08-06 10:57:11.377196516 +0300
+++ loops-g.s   2010-08-06 10:57:11.389197986 +0300
@@ -1,8 +1,8 @@
-   .file   "loops-f.c"
+   .file   "loops-g.c"
    .text
-.globl f
-   .type   f, @function
-f:
+.globl g
+   .type   g, @function
+g:
 .LFB0:
    .cfi_startproc
    pushq   %rbp
@@ -30,6 +30,6 @@
    ret
    .cfi_endproc
 .LFE0:
-   .size   f, .-f
+   .size   g, .-g
    .ident  "GCC: (GNU) 4.4.4 20100630 (Red Hat 4.4.4-10)"
    .section    .note.GNU-stack,"",@progbits

As you can see the code is practically identical.

Cristian Ciupitu
I just want to know how the code inside my loop is being treated in the inside thoughts of a compiler. :)
rob waminal
+3  A: 

You should write the most natural, idiomatic and readable code that clearly conveys your intention. In most scenarios, no one loop is so superiorly performing over the other that you'd sacrifice any of the above for little gain in speed.

Modern compilers for most mainstream languages are really smart at optimizing your code, and can especially target precisely the kinds of good readable codes that people should write. The more complicated your code is, the harder it is for humans to understand, and the harder it can be for compilers to optimize.

Most compilers can optimize tail recursion away, allowing you to express your algorithm recursively (which is the most natural form in some scenarios), but essentially executing it iteratively. Otherwise, a recursion may be slower than an iterative solution, but you should consider all factors before doing this optimization.

If a working, correct, but perhaps a tad slower recursive solution can be written quickly, then it's often preferrable to a complicated iterative solution that may be faster but may not be obviously correct and/or harder to maintain.

Do not optimize prematurely.

polygenelubricants
I see, I like you opinion. You're saying no mater how big you code inside your loop as long as it is coded accordingly, its the compilers problem on how to optimize it am I right?
rob waminal
@rob: Certain things are the compiler's responsibility, certain things are the programmer's responsibility. The programmer is responsible for the big things, the truly harder stuff, the stuff that matters most (Which data structures suit my problem best? This algorithm is quadratic, can I do better? How can I refactor this code to make it more readable, testable, maintainable, reusable?). Good compilers can take care of the little things. Don't waste time on microoptimization. Compilers aren't so dumb that programmers need to micromanage every line and expression.
polygenelubricants
@polygenelubricats, yes, that is very true.. :) but fishing in the deep sea always gets you a bigger fish to fry.. :)
rob waminal