Solved

why do we use local variables in a loop?

Posted on 2004-08-01
16
266 Views
Last Modified: 2010-04-15
Hi all,

Will  code 1 be faster than code 2. why?
THank you.

With Regards
HCK


Code 1:

      for(int n=0; n<N; n++){
             int s = ptr[0] - ptr[1] - ptr[2] + ptr[3];
                                 // other code using s
      }

Code 2:
               int s;
      for(int n=0; n<N; n++){
             s = ptr[0] - ptr[1] - ptr[2] + ptr[3];
                                // other code using s
      }
0
Comment
Question by:hengck23
16 Comments
 
LVL 46

Assisted Solution

by:Sjef Bosman
Sjef Bosman earned 130 total points
Comment Utility
Did you compare them using the assembly listing? Probably you won' see a difference. You might get faster using
    register int n
but it won't differ that much, and it's processor-dependent.
0
 
LVL 8

Assisted Solution

by:a_twixt_in_the_tale
a_twixt_in_the_tale earned 30 total points
Comment Utility
Use something like the zen timer to check which one works faster?
You might have to run it multiple times though to average out everything.

Here's one link
http://www.programmersheaven.com/zone3/cat487/13855.htm

:)
Don
0
 
LVL 19

Assisted Solution

by:mrwad99
mrwad99 earned 90 total points
Comment Utility
Nobody has mentioned the fact that the integer variable 's' is created and destroyed N times in the first loop: in the second it is only created once and destroyed once.

>> int s = ptr[0] - ptr[1] - ptr[2] + ptr[3];

essentially that is copy construction of an integer, which is followed by the destruction (if you want to call it that) of an integer.

>>  s = ptr[0] - ptr[1] - ptr[2] + ptr[3];

That is merely assignment.  No construction, no destruction.

For that reason I strongly believe the second is faster.

And yeah you could put the register specifier in front of the n in the for loop, but modern compilers would optimize the code and do that anyway.

HTH
0
 
LVL 22

Assisted Solution

by:grg99
grg99 earned 30 total points
Comment Utility
Most every compiler will factor out the declaration, as it's MUCH easier to allocate the space ONCE at function entry, rather than allocate it every time the declaration block is entered.  And most compilers will allocate a register for "s" anyway, instead of explicitly allocating it stack space, unless it MUST have an address, such as if it's passed as a reference to another function.  Then again, declaring it in the outer block could confuse the optimizer, if it's a shaky optimizer.

So it could be faster, or could be slower, or could be the same speed.  Pretty dumb question, IYAM.


0
 

Author Comment

by:hengck23
Comment Utility
I read somewhere that says

" Now we put all the pointers, strides and array sizes on
the stack (as local variables), so compiler can safely allocate some
of them on registers (Because the assumption that the current stack frame does
not overlap with heap or data segment is pretty safe :) )
Now compiler may not assume only that storing result to
C_data keeps A_data[...] and B_data[...] the same.
> So this is the next version (that can be further unrolled
and converted to SIMD intrinsics), that requires minimum compiler
intellect:"

>for( ; height--; )
> {
> for( x = 0; x < width; x++ )
> {
> int t0 = A_data[x] + B_data[x];
> int t1 = A_data[x] - B_data[x];
> C_data[x] = (char)t0;
> D_data[x] = (char)t1;
> }
> A_data += A_step;
> B_data += B_step;
> C_data += C_step;
> D_data += D_step;
> }

I was wondering in that case, should be always declared loop variables as local?
(in  this case, i mean int t0 , t1)
0
 
LVL 19

Assisted Solution

by:mrwad99
mrwad99 earned 90 total points
Comment Utility
>> should be always declared loop variables as local?

Well that depends on whether or not  you plan to use the variable outside of the loop at any time.  Most likely the answer to that will be no, so I think that all variables that will be used in a for loop should be local to that loop.

>> for( x = 0; x < width; x++ )

probably better to declare the variable x inside that loop too, i.e.

for(int x=0; ....)

>> (in  this case, i mean int t0 , t1)

well I think that we have given a pretty good description of the pros and cons of local declaration.

It would be interesting to hear *why* you want to know all this...
0
 
LVL 46

Assisted Solution

by:Sjef Bosman
Sjef Bosman earned 130 total points
Comment Utility
Btw, as far as my compiler goes:
    for(int i=1; ...
isn't C, but C++

I agree with grg99. The the scope (visibility) of a local variable is a compile-time restriction, but during runtime there will be no compiler in/decreasing the stackspace just for the sake of a local var. So look at the assembly-listing of your code, you'll see for yourself that space for all local var's will be reserved at the beginning of the function. Something like a
    sub sp,20
 or so. All other stack movements (push/pop) are for arguments of called functions.
0
 
LVL 19

Assisted Solution

by:mrwad99
mrwad99 earned 90 total points
Comment Utility
>> isn't C, but C++

Yeah that is right, but as the original question goes it was used in there so I followed suit.  Perhaps the questioner should have asked this in the C++ area ?!
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 46

Assisted Solution

by:Sjef Bosman
Sjef Bosman earned 130 total points
Comment Utility
So did I. The two languages are so much alike... Both my responses were C-based, but what a C++-compiler makes of it in assembly I wouldn't know. I suppose it won't make a big difference.

Somehow I never grew to like C++, it being "only" a C-dialect of the more interesting kind ;)
0
 
LVL 23

Accepted Solution

by:
brettmjohnson earned 110 total points
Comment Utility
Having implemented compilers, I can tell you that mrwad99 is absolutely incorrect in his
interpretation and grg99 is exactly correct.  In C, the storage space for all local variables
within a function is allocated at function entry (on x86 it looks like: mov bp, sp ; sub bp, ...)

From that perspective, there is little performance difference** between declaring all your
local variables at the beginning  of the function or within scope-limiting blocks.  Indeed,
the primary reason for declaring local variable in a limited scope is for code readability,
maintenance, and encapsulation of valid values.

Indeed, if ptr is never manipulated in the loop, a good optimizing compiler will move this
"loop invariant" code to outside the loop as follows:

    int s = ptr[0] - ptr[1] - ptr[2] + ptr[3];
    for(int n=0; n<N; n++){
         ...
    }


** One place where using limited-scope local variables helps is during the resource allocation
phase of compiler optimization.  Optimizing compilers assign data to resources
(in this case registers and stack memory) and can use the rules of scope to schedule the
availability of those resources. For instance, recursive functions (or any call constructs
with deep call stacks) with significant stack usage can adversely affect performance when
page faults occur to allocate additional stack space.  But consider the following:

int myFunc(...)
{
      {
            char aBuffer[1024];
            ...
      }
      ...
      {
            char anotherBuffer[2048];
            ...
      }
      ...
}

The brain-dead compiler will set aside 3KB of stack space for the two
buffers in the current frame.  An optimizing compiler can apply the rules
of scope to the allocation of stack resources - knowing that aBuffer[] and
anotherBuffer[] are never in scope at the same time, the compiler can
allocate 2KB of stack space and use it for both buffers.  That is an obvious
example, but it is equally applicable to small local variables:

int myFunc(...)
{
      {
            int i;
            ...
      }
      ...
      {
            int k;
            ...
      }
      ...
}

The limited scope helps the resource optimization assign i and k to the
same memory in stack frame, or better still, the same register on the CPU.

0
 
LVL 16

Assisted Solution

by:PaulCaswell
PaulCaswell earned 70 total points
Comment Utility
My policy is generally to reduce the scope of any variable to its minimum. This has two useful results:

1. As was quite clearly described by brettmjohnson et al, some of the more 'intelligent' compilers can optimise it better.

2. If you ever come to chop the contents of the loop out into a separate function, the variables it uses are already 'close' enough.

Generally speaking, if you are worried about code speed, first optimise your algorithm, then use a different language, then twiddle bits. Bit tgwiddling should only be use as a last resort. Always 'optimise' for the next reader of the code.

Paul
0
 
LVL 8

Expert Comment

by:ssnkumar
Comment Utility
hengck23,

How you do programming, many (or most of the) times depend on what is your ultimate objective!
So, if your objective is readability and maintanance of code, then you will not look into whether it is optimized or not.
If optimization is the intention, then your code may lose on the side of readability!

In the first code that you posted, the intention was readability and easy understanding.

But as others have pointed out very clearly and also in detail, the more-intelligent compilers of modern days optimize your code more than what you can make out! If you are able to get back the source from the machine code, then you will not be in a position to recognize that it was the code written by you!!

-ssnkumar
0
 

Assisted Solution

by:aakash_mandhar
aakash_mandhar earned 20 total points
Comment Utility
Ok.. Simple Answer...

To make programmers life easy..

A variable used inside the loop has the scope limited to the loop and cannot be used outside the loop..
You can have programs like....

int main()
{
int a=25;
{
int a=30;
printf("%d\n",a);
}
printf("%d",a);
}

The output will be:
30
25

This means the scope of the inner a is limited to inner loop and does not affect the value of the a outside the loop... When u have such conflicting variable declarations the value of the outer a is pushed onto the program stack and is popped when you exit the loop...

Another advantage is if you have a limited use of the variable and want to make sure you dont use it anywhere else by mistake limit its scope.... :)

Enjoy programming,,,,,,

Regards
Aakash
0
 
LVL 46

Assisted Solution

by:Sjef Bosman
Sjef Bosman earned 130 total points
Comment Utility
Just another reason why I prefer C over C++. IMHO, declarations are only there to facilitate proper translation. They should be kept far away from the actual algorithm. I don't envy the poor sod who has to maintain code that's littered with declarations all over the place. That you use it for loop var's I can understand, but nowhere else.
0
 
LVL 1

Assisted Solution

by:ageraldnaveen
ageraldnaveen earned 20 total points
Comment Utility
From point of view,

both the code snips, will perform equally in speed.. there is no differentiating factor in terms of speed. however, the code 2 snip, would be holding that sizeof(int) bytes allocated for the variable "s" even after the for loop is done. thats all. If the variable "s" is declared inside the loop, there is no loss in performance at all.. there is nothing called as construction and destruction of a primitive data type like "int". All that is done is changes to the ESP stack pointer, which would anyway happen when there is atleast one local variable. So, code 1 is the better one, when the value of "s" is no longer required outside the for loop, and it costs no performance loss.
0
 
LVL 46

Assisted Solution

by:Sjef Bosman
Sjef Bosman earned 130 total points
Comment Utility
If variables declared inside a loop were also created at that moment, the implementation would make snip 2 last longer, for temp. var's must be created and removed each time the loop starts.
So I cannot imagine the stack moves (please don't quote Galilei... ;)
0

Featured Post

Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Have you thought about creating an iPhone application (app), but didn't even know where to get started? Here's how: ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ Important pre-programming comments: I’ve never tri…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now