Variable declarationEfficiency

Hi,

If I am looping over a collection which is more efficient?

for (Iterator<HashMap><String, Object>> iterator _myCollection.iterator(); iterator.hasNext();){

HashMap<String, Object> trade = iterator.next();

String myStringVar = (String) trade.get("myIndex");

or

String myStringVar =null;

for (Iterator<HashMap><String, Object>> iterator _myCollection.iterator(); iterator.hasNext();){

HashMap<String, Object> trade = iterator.next();

myStringVar = (String) trade.get("myIndex");

[787 byte] By [java_swing_dudea] at [2007-11-26 17:42:31]
# 1
They're the same.The VM allocates stack space for all a method's variables on method entry.The only difference is that the pointless null assignment in the second one wastes a few clock cycles.
jverda at 2007-7-9 0:10:43 > top of Java-index,Java Essentials,Java Programming...
# 2
There is no difference with respect to efficiency, but the first case is more likely to produce correct code (i.e., reduce bugs).
paulcwa at 2007-7-9 0:10:43 > top of Java-index,Java Essentials,Java Programming...
# 3
Thank you, Do you have any useful links on how the Java VM handles this kind of stuff?
java_swing_dudea at 2007-7-9 0:10:43 > top of Java-index,Java Essentials,Java Programming...
# 4
Both work in same way, as ur retrieving String (immutable object) from the Hashmap.
I_LOVE_JAVAa at 2007-7-9 0:10:43 > top of Java-index,Java Essentials,Java Programming...
# 5
There's the VM spec. But I don't think this behavior is part of the spec, so it wouldn't have to be that way. Just that it's been a very common way of doing things since long before Java was born. http://java.sun.com/docs/books/vmspec/2nd-edition/html/VMSpecTOC.doc.html
jverda at 2007-7-9 0:10:43 > top of Java-index,Java Essentials,Java Programming...
# 6

Yeah it's mostly about what bytecode is produced. The VM spec may shine some light on that but probably won't explain this case in particular.

You can also play with the javap tool to look at bytecode (or bytecode mnemonics, really).

Re: the first way producing less bugs, that's because in practice keeping scope as tight as possible and data as private and local as possible reduces unexpected interactions, and unexpected interactions are a prime source of bugs.

paulcwa at 2007-7-9 0:10:43 > top of Java-index,Java Essentials,Java Programming...
# 7

> Both work in same way, as ur retrieving String

> (immutable object) from the Hashmap.

That's not the issue though.

He's asking whether putting the variable declaration inside a loop has any performance effect. It doesn't, but the reason has nothing to do with the fact that the String is immutable or retrieved from the map.

jverda at 2007-7-9 0:10:43 > top of Java-index,Java Essentials,Java Programming...
# 8
Is there ever a case when creating a new object inside a loop will cause performance / memory issues?
java_swing_dudea at 2007-7-9 0:10:43 > top of Java-index,Java Essentials,Java Programming...
# 9

> Yeah it's mostly about what bytecode is produced.

> The VM spec may shine some light on that but

> probably won't explain this case in particular.

>

> You can also play with the javap tool to look at

> bytecode (or bytecode mnemonics, really).

The bytecode really isn't the issue. It's what the VM does when running that bytecode.

> Re: the first way producing less bugs, that's because

> in practice keeping scope as tight as possible and

> data as private and local as possible reduces

> unexpected interactions, and unexpected interactions

> are a prime source of bugs.

Yes, that's a very good point. Thanks for fleshing out the discussion.

jverda at 2007-7-9 0:10:43 > top of Java-index,Java Essentials,Java Programming...
# 10
> The bytecode really isn't the issue. It's what the VM> does when running that bytecode. Eh? The bytecode in the two cases may be slightly different, but the differences when the VM executes it will be minor or non-existent. What were you referring to?
paulcwa at 2007-7-9 0:10:43 > top of Java-index,Java Essentials,Java Programming...
# 11

> Is there ever a case when creating a new object

> inside a loop will cause performance / memory issues?

Now you're talking about something completely different.

Declaring a variable != creating an object.

Yes, creating an object inside a loop can cause performance issues, if it's an expensive object to create and it's a tight loop, then yeah, that gets expensive.

But your initial post has nothing to do with object creation. It's just variable declaration. If your method has ten local reference variables, then, regardless of where in the method they're declared, the VM will add 10 * 4 = 40 to the stack pointer to make room for those variables.

A reference variable is separate from the object it points to.

jverda at 2007-7-9 0:10:43 > top of Java-index,Java Essentials,Java Programming...
# 12

> Is there ever a case when creating a new object

> inside a loop will cause performance / memory issues?

Well, if you create really heavy objects in a loop, that will have a performance effect, but it may be necessary to do so.

And if you create a lot of objects and then never throw them away, it can create memory issues. That's more of a "never throwing them away" issue than a loop issue, but a loop would help you make this mistake, I guess.

In general: first worry about keeping your code correct. Then worry about keeping your code clean. Worry about efficiency last. You'll probably be too busy worrying about the first two things to worry about the third. And usually the sort of efficiency gains on the level you're asking about are at best so minor as to be microscopic.

paulcwa at 2007-7-9 0:10:43 > top of Java-index,Java Essentials,Java Programming...
# 13
Ok, Would this be a problem inside the loop?String bookingID = new String((String)trade.get("BookingID"));
java_swing_dudea at 2007-7-9 0:10:43 > top of Java-index,Java Essentials,Java Programming...
# 14

> > The bytecode really isn't the issue. It's what the

> VM

> > does when running that bytecode.

>

> Eh? The bytecode in the two cases may be slightly

> different,

I haven't run javap, but other than the extra null assignment, and possibly which local gets which index, I'd expect the bytecode to be identical.

> but the differences when the VM executes

> it will be minor or non-existent. What were you

> referring to?

When executing, in both cases, the VM will simply add a certain offset to the SP on method entry. The only execution difference will be brought about by the superfluous null assignment.

jverda at 2007-7-9 0:10:43 > top of Java-index,Java Essentials,Java Programming...
# 15

> Ok, Would this be a problem inside the loop?

>

> String bookingID = new

> String((String)trade.get("BookingID"));

The new String part is pointless.

String bookingID = (String)trade.get("BookingID");

And if your on >= 1.5 and using generics properly, you won't even need the cast.

You're not creating an object here, just calling a method (which may create one or more objects as part of its execution, but the String object already exists, and you're just getting a reference to it).

If it's the same object every time through the loop, you could do that outside the loop to save a few cycles, but fetching from a map is fast, so it probably won't be a big savings, and, as mentioned earlier, you're probably better off limiting the scope by keeping it inside the loop unless and until you determine that it is actually causing performance issues.

jverda at 2007-7-21 17:11:25 > top of Java-index,Java Essentials,Java Programming...
# 16

> Ok, Would this be a problem inside the loop?

>

> String bookingID = new String((String)trade.get("BookingID"));

It's a problem because you're unnecessarily creating Strings. Being inside a loop aggravates the problem but otherwise isn't an issue.

You're unnecessarily creating strings because the get() returns a string object (or the cast fails and you get a class cast exception). Once you have that string object, passing it to "new String(theObject)" doesn't do anything useful; it just creates another String object when the first one was fine to begin with.

paulcwa at 2007-7-21 17:11:25 > top of Java-index,Java Essentials,Java Programming...
# 17

> I haven't run javap, but other than the extra null

> assignment, and possibly which local gets which

> index, I'd expect the bytecode to be identical.

I was anticipating a minor and inconsequential rearrangement in the order of instructions.

@OP: why not try writing some tests and seeing if the bytecode actually is different or not?

paulcwa at 2007-7-21 17:11:25 > top of Java-index,Java Essentials,Java Programming...