• Post Reply Bookmark Topic Watch Topic
  • New Topic

Declare variables as close as possible...  RSS feed

 
Ranch Hand
Posts: 79
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Is it unwise to declare variables inside of a loop?



or




John Abong
 
Ranch Hand
Posts: 49
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Generally, if possible you should declare variable in the smallest possible scope you can. However, if it means you're creating objects in a loop as your example shows, that is very bad for performance if you don't have to do it. If you do have to, then it's fine. In your specific example below, I would choose your second option for the performances sake. However, you have to evaluate on a case-to-case basis.
Hope this helps
 
(instanceof Sidekick)
Ranch Hand
Posts: 8791
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I like this part: if possible you should declare variable in the smallest possible scope you can. You'd have to define "very bad" for me, and demonstrate it in a real test to make me do anything else. Make that kind of optimization only after you can prove that you have a problem and you know where it is.
 
Ranch Hand
Posts: 101
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In my opinion this is a gray area, and as John has said it often comes down to a case-by-case basis.

A "start" - if you will, is to consider the following:

How expensive is this object to create? (Strings are pretty cheap, Calendar's are not).
How many time's are you looping?
Could someone mistake this variable for being useful outside of the scope of the loop?
If so, what's the risk if that happens? How hard would it be to detect?

I have seen instances where expensive and risky objects are created outside of the loop and right after the loop complets the object reference is set to null with a comment explaining why.
 
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[John M]: However, if it means you're creating objects in a loop as your example shows, that is very bad for performance if you don't have to do it.

In the example shown, the poster is not creating any objects inside the loop, in either version of the code. First, declaring a reference variable inside a loop is not creating an object. Second, using a String literal is not creating an object - at least, an object is not created more than once. The String literal causes a String object to be created once when the class is loaded, but after that, that same object is re-used. So in practice, the difference between the two code examples shown is negligible. The first version of the code does assign s to the String reference, and there's really no need to do that more than once since it never changes. So the second version is a tiny bit more efficient - but it really matters very little.

In general though, if a variable never changes, there's little reason to set it repeatedly inside a loop - you might as well set it just once outside the loop. If the variable did get different values inside the loop, then it would make sense to just declare it inside the loop.
[ November 15, 2007: Message edited by: Jim Yingst ]
 
John Abong
Ranch Hand
Posts: 79
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
smallest possible scope


This is what I was looking for. Thanks, John!
 
John Abong
Ranch Hand
Posts: 79
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I posted before I saw the updates:

For too long I�ve �tweaked� code without regard to any formal rules, in my self-led journey. I�m trying to correct that.

ALL responses are meaningful to this end; the variety is also instructive.

Thanks, again.

J Abong
 
John Abong
Ranch Hand
Posts: 79
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
...same question posed differently...

This is somewhat, �loaded� and cryptic but the question is; is an object created in the absence of the new operator by doing this:



Pardon my deliberate attempt to be obscure.

Thanks, John Abong

[ November 30, 2007: Message edited by: john abong ]
[ November 30, 2007: Message edited by: john abong ]
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No.

Of course we have no idea what happens inside ClassTypeXMethod(). There's a good chance it creates an object, since it returns a reference to na object. And ClassTypeXCONSTANT is probably initialized with an object somewhere - also not shown. But in the code shown, no objects of any type are created. Unless, perhaps, ClassTypeXMethod() takes a vararg, in which case an array is created whenever the method is called. That's probably not what you mean, but it's hard to tell when all the details are obfuscated like this.
 
John Abong
Ranch Hand
Posts: 79
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you, Jim, great job deciphering my
obfuscated
post!

Okay so the way I understand this is that:

if there's a chance that a reference to an object will be returned, thereby creating an object, I wouldn't want this to happen inside of a loop.

Am I getting warm?

John Abong
 
Sheriff
Posts: 4012
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Stan James:
I like this part: if possible you should declare variable in the smallest possible scope you can. You'd have to define "very bad" for me, and demonstrate it in a real test to make me do anything else. Make that kind of optimization only after you can prove that you have a problem and you know where it is.


I wonder if for this particular case a little test is in order - just for learning purposes, assuming that bad or even very bad isn't an issue.




JY: Of course we have no idea what happens inside ClassTypeXMethod(). There's a good chance it creates an object, since it returns a reference to an object.


Continuing along the obfuscation trail... (since revealing the class name and method would spoil the fun for other Cattle Drivers. It's where we get to make believe we work for a high security firm, and we get to say that cool thing about what happens if we tell you too much. )

ClassTypeXMethod() does a simple calcuation on a ClassTypeX object and returns the result as a ClassTypeX object.

When you say there's a good chance that an object is being created, how does one go about knowing for sure?
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[John]:

if there's a chance that a reference to an object will be returned, thereby creating an object, I wouldn't want this to happen inside of a loop.

Am I getting warm?


Um, not really. Returning a reference doesn't "thereby" create an object. But it implies that an object exists somewhere. Either it was created, or it already existed. As for "I wouldn't want this to happen inside of a loop" - well, creating an object is hardly the end of the world, even inside a loop. If there really is an object being created (not merely somethign that we think might create an object - let's not worry too much about monsters under the bed) then it might make sense to look at whether it is necessary to do it inside the loop, or outside. If outside is possible, then it's probably preferable (all other things being equal). But if it's not possible, it's not a big deal.

[Pauline]: When you say there's a good chance that an object is being created, how does one go about knowing for sure?

Well, generally by looking at the code. Or perhaps by checking the documentation, if that's easier (e.g. if it's a method you didn't write, and just have in a jar file). Generally in the code, you would look to see if a new operator is used. If we're talking about a String or some sort of Number, then there are various other ways to create new objects too, with + or autoboxing. And arrays can be created with an initialization expression like

Oh, and exception objects can be created by committing various errors. I may be forgetting one or two other ways. Most of these are fairly obvious if you look at the code though.
 
Sheriff
Posts: 9082
12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In general I think most Objects are created by using the keyword new. Sometimes you can access an object with the dot operator -- for example, System.out.println() where we are calling the println() method and System.out is an Object. Have we created a new PrintStream object by using System.out in our code?

Sometimes it is hard to not be confused by the difference between the reference to the Object and the Object itself. There really is no difference between
Object object;
object = new Object();

and
Object object = new Object();

as far as the creation of the object is concerned, so you wouldn't be reducing Object creation by using
Object object
while (blah)
{
object = new Object();
}
instead of

while (blah)
{
Object object = new Object();
}

As Jim said, Strings, arrays and autoboxing (in Java 5 and up) have other ways of creating objects without using the new keyword.

Also note that you can call a static method on a class without creating an object of that class first. So you can call System.currentTimeMillis() without creating a new System object first or Integer.parseInt() without creating an Integer object.
 
John Abong
Ranch Hand
Posts: 79
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Then may I summarize (as a beginner might)�

JY: reference to an object may imply that one already exists �somewhere�.
JY: Placement of the instantiating reference is not especially critical.

PM: How can one tell when an object is being created?

JY: Look through code for the new operator, etc.
JY: Understand the implicit nature of object creation, for ex.; +, autoboxing, exception errors, etc.

MdQ: Static methods can also be invoked without creating new objects.

JA: Thus, ��worrying too much about monsters under the bed� aside, excluding cases of implicit instantiation and instantaneously or otherwise �cleaned� objects, the new operator does the storage allocating and the reference variables point to this location.

Further, the automatic nature of the garbage-collectable-heap recoups the memory, once inhabited by objects, referenced by reference variables.

So, focus on readability, understand the API, method invocation, and memory dynamics...
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Half of those "JY" quotes above have nothing to do with me or any previous posters in this thread. Did you mean to label them JA, as new statements by you?

JY: reference to an object may imply that one already exists “somewhere”.
JA: Placement of the instantiating reference is not especially critical.


I have no idea what an "instantiating reference" is. That term seems meaningless. A reference does not cause instantiation. Some other code does that - usually by using "new". Placement of code that creates objects may be critical, or not, but it can't be simplicifed down to "don't create object in a loop". Perhaps "don't create objects in a loop if you don't need to" - that's probably a decent guideline in general.
 
Sheriff
Posts: 1367
18
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As to how to tell if an Object is being created... is there any good way of asking the compiler?
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, sort of, but it's not really JiG: Beginner material. You can use javap to disassemble a class file to tell you more exctly what is happening. This allows you to dscover that, for example, autoboxing to Integer is done using the static method Integer.valueof(), so if you want to know if a new instance is really created in a given situation, you would need to look at the source code of that method. A tool like javap can be useful for discovering those details. but it still may require work to figure out everything that happens.

Perhaps the easiest thing to do would be to use an IDE with a good debugger, like IntelliJ or Eclipse. Set a breakpoint on the new Object() constructor, so that it will stop on that breakpoint every time a new object is created. Run your program and see what happens.

On a more practical level, this is all seeming like a disproportionately large amount of time to spend on a relatively unimportant question. Most of the time it's obvious when a new object is created, because the code says "new". In many other cases it just doesn't matter whether a new object is created or not. In general it only matters if there's a performance problem. And if there's a performance problem, at that point you can profile the code and see where the problem is coming from. Premptively worrying about every single possible source of object creation sounds like a lot of work for very little benefit.
 
John Abong
Ranch Hand
Posts: 79
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Point taken! ...was just going on the premise of
No question too simple or too small.


Your input has been very illuminating.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!