# Declaring variables in loops.

This topic is 4411 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

So today I finally ask a question I've had for quite a while... Is there a different between....
int x;
for(some big loop)
for(some even bigger loop)
for(wowz0rs loop)
{
x = return_something(anything);
use_variable(x);
}
... and
for(some big loop)
for(some even bigger loop)
for(wowz0rs loop)
{
int x = return_something(anything);
use_variable(x);
}
I've already concluded that the later code would be a very bad idea for non-primitive types, but I can't decide for primitives.

##### Share on other sites
In either case (primitive or non-primitive type) the compiler should will optimize it. The real question is which scope the variable should have. If it's only supposed to exist in the innermost loop then it belongs there, otherwise it should be outside.

##### Share on other sites
When you declare x and then pass it as an argument, you are only passing the value, not the location. It doesn't matter where it was declared.

##### Share on other sites
Quote:
 Original post by RaIn either case (primitive or non-primitive type) the compiler should optimize it. The real question is which scope the variable should have. If it's only supposed to exist in the innermost loop then it belongs there, otherwise it should be outside.

I'm not sure the compiler could optimize this to the point where it becomes merly preference...
(This is what I ment by non-primitives; eg.. not just the reference but the instancing of the object itself.)

for(some big loop)   for(some even bigger loop)      for(wowz0rs loop)      {         ColorOperator x = new ColorOperator();         x.Color = return_something(anything);         use_variable(x);      }

.. but in the case of primitives (Or non-instanced non-primitives), it would be in my best interests to put it inside the loop since its scope doesn't exceed it.

##### Share on other sites
I think what he meant is that the compiler optimizes the space allocated for local variables. Initialization is optimized (or not) separately. Static initialization would be done at compile time, however.

It ends up being up to preference about how you like your scope...

##### Share on other sites
Quote:
 Original post by TheveninI'm not sure the compiler could optimize this to the point where it becomes merly preference...(This is what I ment by non-primitives; eg.. not just the reference but the instancing of the object itself.)for(some big loop) for(some even bigger loop) for(wowz0rs loop) { ColorOperator x = new ColorOperator(); x.Color = return_something(anything); use_variable(x); }.. but in the case of primitives (Or non-instanced non-primitives), it would be in my best interests to put it inside the loop since its scope doesn't exceed it.

If you are using heap allocation (i.e., new+delete), then reusing the object might provide some benefit. But otherwise, allocate it in the scope it is used. In fact, it might even open more optimization opportunities for the compiler if the smallest scope.

It looks though like you are using Java/C#. In that case, all objects are allocated on the heap. So there might be some benefit to reusing objects. However, it is nowhere near as big a benefit as it once was because of the much better garbage collectors and heap allocators in modern virtual machines.

##### Share on other sites
I don't remember where I heard it from, but I was once told that you should declare a variable outside of the loop if there's a good probability that it'll be assigned the same value more than once.

For example:

int value;while(true){	value = ...;	// ...}

Here, in the first iteration of the loop, the number 5 might be assigned to value.. And in the second iteration, the number 5 might again be assigned to value (perhaps a very very VERY slight performance gain, but nothing to wow over).

while(true){	int value = ...;	// ...}

I usually use the above when I know that the number assigned to value could be anything, and thus such micro-optimising would prove to be pointless.

In any case I would definitely favour whichever method makes my code cleaner and easier to manage.

EDIT: For anything other the standard types (int, float, etc) it is a completely different story. You wouldn't really want to create and destroy a complex object in the loop over and over.

##### Share on other sites
Quote:
Original post by etothex
Quote:
 Original post by TheveninI'm not sure the compiler could optimize this to the point where it becomes merly preference...(This is what I ment by non-primitives; eg.. not just the reference but the instancing of the object itself.)for(some big loop) for(some even bigger loop) for(wowz0rs loop) { ColorOperator x = new ColorOperator(); x.Color = return_something(anything); use_variable(x); }.. but in the case of primitives (Or non-instanced non-primitives), it would be in my best interests to put it inside the loop since its scope doesn't exceed it.

If you are using heap allocation (i.e., new+delete), then reusing the object might provide some benefit. But otherwise, allocate it in the scope it is used. In fact, it might even open more optimization opportunities for the compiler if the smallest scope.

Well, by not putting the x variable before the loops (In this case), the memory manager is now having to new/delete...

big*bigger*wowz0rs

...many ColorOperators. And if my math is correct, this is alot of unnecessary processing. Enough to the point where I could foresee SiCrane saying something along the lines of...

Quote:
 Original post by SiCraneI mean this in the nicest way possible, but what the hell is wrong with you? [...]

##### Share on other sites
If the object value is not going to be changed, apparently I'll put it outside of the loop and have it to be const (I'm not considering about compiler optimizations here though).

If not, my choice depends on the complexity of the constructing object:
• For fundamental types, I'd prefer putting it inside the loop.
• For other types that are more complex than Vector3, I'd prefer putting it outside.

: Beaten by Wavarian.

##### Share on other sites
Quote:
 Original post by ender7771When you declare x and then pass it as an argument, you are only passing the value, not the location. It doesn't matter where it was declared.

Yuppers, but is there a performance hit for putting it in the for loop.

I know that the C# compiler will optimize just about everything you write, but that doesn't always produce an acceptable solution; this part of the code is in the heart of my graphics procedures so I'm not even worried about "premature optimization".

##### Share on other sites
Quote:
Original post by Thevenin
Quote:
 Original post by ender7771When you declare x and then pass it as an argument, you are only passing the value, not the location. It doesn't matter where it was declared.

Yuppers, but is there a performance hit for putting it in the for loop.

I know that the C# compiler will optimize just about everything you write, but that doesn't always produce an acceptable solution; this part of the code is in the heart of my graphics procedures so I'm not even worried about "premature optimization".

Java (and I would assume C#/.NET) uses a generational garbage collector that is heavily optimized for very short-lived objects, those being the most common.

So while I would say that if it's simple to reuse the object, I would, but I wouldn't be too concerned about it unless you really were trying to squeeze the last bit of performance out of the loop - in which case you can find out by trying both and see which is faster, which will give you a conclusive answer.

##### Share on other sites
Quote:
 Original post by Skeleton_V@TIf [the object is mutable], my choice depends on the complexity of the constructing object:For fundamental types, I'd prefer putting it inside the loop.For other types that are more complex than Vector3, I'd prefer putting it outside.

For objects that are more 'complex' than simple Vectors, you've got to choose based on more than construction. If your assignment semantics are more expensive than construction/destruction, and efficiency of the loop is a concern, declaring/initializing the object inside the loop would be preferrable. Often this isn't the case, but it probably should be pointed out anyway.

##### Share on other sites
holy hell, how often do you guys need "premature optimization" yelled at you?

variables are declared as local as possible <PERIOD>
everything else is ugly performance tweaking, thats the last thing to worry about. and the compiler will most likely optimize it anyway.

##### Share on other sites
Quote:
 Original post by RaIn either case (primitive or non-primitive type) the compiler should will optimize it.
Non-primitive type's constructor may have such side-effects that this optimization would lead to different behaviour.

##### Share on other sites
Quote:
 Original post by maximALholy hell, how often do you guys need "premature optimization" yelled at you?variables are declared as local as possible everything else is ugly performance tweaking, thats the last thing to worry about. and the compiler will most likely optimize it anyway.
Who are you to say whether the original poster is optimizing prematurely or not? OP even said: "this part of the code is in the heart of my graphics procedures so I'm not even worried about "premature optimization"." Sometimes ugly performance tweaking is necessary.

##### Share on other sites
Quote:
 Original post by maximALholy hell, how often do you guys need "premature optimization" yelled at you?

Believe it or not, there are those that read this forum for which understanding how your objects are created/assigned/destroyed is not premature at all. Rather, I'd suggest that blanket adherence to one particular method, without regard for, IMO, important issues such as those I mentioned above is much worse than premature optimization (for built-in types, this is of course a non-issue, and has nothing to do with optimization - although there are certain circumstances where the state of an uninitialized variable is a concern).

##### Share on other sites
i didn't just mean the op. there are other posts, too, promoting thoughtless use of that.