Scope Best Practice

  • Thread starter Thread starter John Baro
  • Start date Start date
J

John Baro

What are peoples thoughts on the following.

for(int i = 0; i < 100; i++)
{
int b = 10;
}

or

int b;
for(int i = 0; i < 100; i++)
{
b = 10;
}

//b is not needed anywhere else.

I would like to know whether people prefer to declare it outside scope and
and not recreate it each time or the other way.

Personally (There are much more knowledgeable people here than I) I prefer
the first way as it keeps scope "tight".
ie dont declare it where you dont need it.

Cheers
JB
 
Hi John,

I guess the answer to the problem lies in the question "What is the cost of
creating a new object versus the cost of maintaining it in memory?"

In the first case, the object is ready for GC once the loop is complete (
and hence it gets out of scope) this is light on the memory but has an
additional overhead of creating the object everytime.

In the second case, the object is not freed until the entire loop (100
times ) is completed.I think that it is ready for GC once the loop is over
even if it remains in scope because it is not being referenced anywhere
else. In this case, the memory is held by b for the entire duration of the
execution of the loop, but does saves on the time for creation.


Your best bet is to determine what is the nature of the object that you are
trying to reference ( as in is it a very heavy object requiring a lot of
time for creation) and what is the bottleneck in your application ( speed or
memory) and then choose the appropriate style.

I must also mention here that there is a middle path that one can take while
faced with this kind of problem. the solution lies in weak referencing where
in, the object is resurrected even if it is out of scope (but is not garbage
collected)

Hope that helps

-Diwakar
 
In the case of an integer, you'll find your first way runs faster, in fact.

However, if you're accessing a class which may take extra time to
instantiate, if you can create it outside of the for loop, then it may very
well make a noticable difference.

MyClass class1 = new MyClass()
for(int i = 0; i < 100; i++)
{
class1.b = 10;
// use class1.b
}

versus

for(int i = 0; i < 100; i++)
{
MyClass class1 = new MyClass()
class1.b = 10;
// use class1.b
}

Of course, there will be times when you need to create the class in a for
loop.

Just some thoughts,
Chris A.R.
 
Here, my rule is "the less you expose, the better". So, if you can reduce
the scope to a block, do it.

There are nevertheless cases where performance forces you to declare the
variable outside the loop. For example, if you have a loop that reads data
and you need a byte[] buffer inside the loop, it is better to allocate it
once outside the loop than to allocate a new buffer at every iteration.

Bruno.
 
Diwakar R said:
I guess the answer to the problem lies in the question "What is the cost of
creating a new object versus the cost of maintaining it in memory?"

It's not really...
In the first case, the object is ready for GC once the loop is complete (
and hence it gets out of scope) this is light on the memory but has an
additional overhead of creating the object everytime.

No object is actually created at all here, as it's an integer.
In the second case, the object is not freed until the entire loop (100
times ) is completed.I think that it is ready for GC once the loop is over
even if it remains in scope because it is not being referenced anywhere
else. In this case, the memory is held by b for the entire duration of the
execution of the loop, but does saves on the time for creation.

b is a local variable. It just takes up a stack slot, and that stack
slot won't be affected by the position at all. It's not garbage
collected.

If you *do* have an actual object, the semantics of whether you want to
initialize a new instance each time or reuse an existing one will
*usually* be determined by the nature of the operation, not by
performance criteria.
I must also mention here that there is a middle path that one can take while
faced with this kind of problem. the solution lies in weak referencing where
in, the object is resurrected even if it is out of scope (but is not garbage
collected)

I don't really see how that's relevant here, but weak references are
only *occasionally* a good idea, IMO. They complicate things
considerably, lowering readability. I don't think this kind of
situation is appropriate for weak reference use at all.
 
Chris A. R. said:
In the case of an integer, you'll find your first way runs faster, in fact.

I don't believe that's true. Here's an example class:

using System;

public class MyForm
{
static void Main()
{
DeclaredInside();
DeclaredOutside();
}

static void DeclaredInside()
{
for(int i = 0; i < 100; i++)
{
int b = 10;
Console.WriteLine(b);
}
}


static void DeclaredOutside()
{
int b;
for(int i = 0; i < 100; i++)
{
b = 10;
Console.WriteLine(b);
}
}
}

Compiling the above yields exactly the same IL for DeclaredOutside and
DeclaredInside, apart from the order of the local variables (in one, b
is stack location 0 and i is stack location 1; in the other they're
reversed).

Of course, if you have a benchmark or something similar showing that
declaring it outside *is* faster, I'd be interested in seeing it.
 
John Baro said:
What are peoples thoughts on the following.

<snip>

If you're truly assigning a new value to the variable at the start of
each iteration of the loop, it will make no difference to the speed of
the code (unless you're very unlucky in terms of which variables end up
enregistered - the local variables may have different locations in the
stack).

As others have said, if there's an expensive object you can preallocate
and then reuse, that's a different matter.
Personally (There are much more knowledgeable people here than I) I prefer
the first way as it keeps scope "tight".
Agreed.

ie dont declare it where you dont need it.

Indeed - "declare at the point of first use" is a good general rule.
 
I wouldn't claim to be more knowledgeable than you for answering your
query so I will abstain with an abstract answer. The difference between
the two snippets is like jogging with a treadmill and jogging on a
jogging track. The amount of energy spent may be the same but the result
may not be.

with regards,


J.V.Ravichandran
- http://www.geocities.com/
jvravichandran
- http://www.411asp.net/func/search?
qry=Ravichandran+J.V.&cob=aspnetpro
- http://www.southasianoutlook.com
- http://www.MSDNAA.Net
- http://www.csharphelp.com
- http://www.poetry.com/Publications/
display.asp?ID=P3966388&BN=999&PN=2
- Or, just search on "J.V.Ravichandran"
at http://www.Google.com
 
John said:
What are peoples thoughts on the following.

for(int i = 0; i < 100; i++)
{
int b = 10;
}

I always go with the above, in this situation.

/Declaring/ the variable outside of the loop gives the false impression
that it will be /used/ outside of the loop. It also requires one extra
unnecessary line in a method, in cases like this (one for declaration
and one for assignment).

Also, as others have mentioned, both snippets compile to the exact same
IL code.

<snip>
 
Back
Top