Sign in to follow this  
jamesleighe

When to Declare Variables in Tight C++ Loops

Recommended Posts

Is is better to do say:

[code]
Object* object;

for (int i = 0; i < 1000000; ++i)
{
object = GetSomeObject (i);
*do stuff with object*
}
[/code]

or

[code]
for (int i = 0; i < 1000000; ++i)
{
Object* object;

object = GetSomeObject (i);
*do stuff with object*
}
[/code]

The second way it seems that I have to recreate the variable for every loop, but is this really true? Also, remember that a practical use would involve many variables being 'recreated'.

Thanks!

Share this post


Link to post
Share on other sites
They're both the same.

"[font="Courier New"]Object*[/font]" is a primitive type, so there's no cost for "creating" one every iteration.

If instead you had an "[font="Courier New"]Object[/font]" it would be different -- e.g.:[code]class Object
{
public:
Object() {
//do something expensive here
}
~Object() {
//do something expensive here
}
};
...
for (int i = 0; i < 1000000; ++i)
{
Object object;//calls Object::Object() every iteration

object = GetSomeObject (i); //calls Object::operator=(const Object&)

}//calls Object::~Object() every iteration[/code]

Share this post


Link to post
Share on other sites
In C++ you should prefer [b]initialization[/b] over [b]assignment[/b].
[code]for (int i = 0; i < 1000000; ++i)
{
Object* object = GetSomeObject(i);
*do stuff with object*
}[/code]

Share this post


Link to post
Share on other sites
[quote name='MartinsM' timestamp='1307623122' post='4821290']
In C++ you should prefer [b]initialization[/b] over [b]assignment[/b].
[code]for (int i = 0; i < 1000000; ++i)
{
Object* object = GetSomeObject(i);
*do stuff with object*
}[/code]
[/quote]

sorry to hijack, but why and where can I find more about initialization vs assignment?

Share this post


Link to post
Share on other sites
Declare local variable as close to its using code as possible.
Put local variable only to the scope to the one real use it.
So I prefer to second one.

But as some other mentioned, object is different, but object pointer is not.

Share this post


Link to post
Share on other sites
Since a loop has no stack of its own I'm pretty sure both of the examples you gave turn into the same code after the compiler is done processing it.

[source]
void Function (void)
{
int a;

for (int i = 0; i < 1234; i++)
{
float b;

b = SomeOtherFunction();
}
}
[/source]
Is going to turn into:
[source]
void Function (void)
{
int a;
float b;

for (int i = 0; i < 1234; i++)
{
b = SomeOtherFunction();
}
}
[/source]

Share this post


Link to post
Share on other sites
@procgen
Stack? It might end up in registers, as constants or eliminated entirely depending on the nature of SomeOtherFunction().

@OP
Modern compilers are extremely good. If you're worried about speed you'll want to be looking at the [b]high level[/b] [u]algorithms[/u] and[u] data structures[/u] you are using. In your example, you might be able to avoid processing all 1,000,000 objects with a clever data structure that groups objects spatially, for example. This would blow any low level optimisations out of the water.

When you are doing such low level optimisations, you'll need to be profiling and looking at the assembly. Without doing so, you're effectively stumbling in the dark and hoping your program will be faster when you're done.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this