java.util.Vector v= someobj.getVectorFromSomewhere(); String element=null; for(int i=0;i < v.size();i++) { element=(String)v.elementAt(i); ... } Once the declaration of 'element' is made inside (hence: each time), once outside the loop. The question is: What is the "internal" difference between these two possibilities?
* Is one way faster than the other? Which one? * Which method consumes more memory - if at all? * Forgetting garbage collection for a moment: are "memory leaks" / "dangling pointers" more / less possible in one method? In which one?
Wendal Park
Ranch Hand
Joined: Aug 28, 2001
Posts: 39
posted
0
Use the second method, for sure! Then for each element in the Vector, you just use the same reference assigning to it, thus saving memory usage. Also, there won't be something like "dangling pointers" in Java ... the closest relative would be the NullPointerException (a Runtime Exception). This is something due to accessing an index outside the size of an Array or String in most cases. So it is kind of irrelevant in this case. Since you probably won't need the previous String object retrieved from the Vector after each loop, why do you need new reference to it? And this may trigger GC for large Vector size ... Therefore usign one String reference (like in 2nd case) can surf the purpose, although both ways should work fine afterall.
On my system (Windows, JDK 1.4.1), this shows about a 20 percent difference (to my surprise) in favor of declaring the variable outside the loop. This may differ on your system, of course. I don't think there should be any differences in memory consumption - as far as I know, a local variable inside the loop will be reused, two. There are other implications, though. If a variable only gets used inside a loop, it communicates much better if it also gets declared there. It also simplifies refactorings like extract method. Remember - generally maintenance is much more important than performance!
The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Jim Yingst
Wanderer
Sheriff
Joined: Jan 30, 2000
Posts: 18652
posted
0
Ilja - using your program on my system (JDK 1.4.1 on Win XP) I observed that declaring outside the loop was more like twice as fast as declaring inside the loop ( !) Then I tried reversing the order of the tests, and found the opposite result. I think you're just observing JIT effects. What's particularly odd is that your outer "count" loop manages to reset this effect, so that the third test run takes twice as long again, like the first, and the fourth is comparable to the second. Very strange. That damn HotSpot sure makes accurate performance testing difficult. Running the tests in separate JVM instances, both inner and outer declarations seem to give the same results (subject to random variations in each execution). [ January 24, 2003: Message edited by: Jim Yingst ]
"I'm not back." - Bill Harding, Twister
Peter den Haan
author
Ranch Hand
Joined: Apr 20, 2000
Posts: 3252
posted
0
Vector... Yech. Who still uses Vector. There is zero, zip, zilch performance difference. Upon entry into a method, a stack frame is allocated that is large enough for ALL variables declared in any scope within the method. Compile both your code samples and use javap -c to decompile the class files. The compiler generates completely identical code for both. It doesn't get more conclusive than that - Peter
Ilja Preuss
author
Sheriff
Joined: Jul 11, 2001
Posts: 14112
posted
0
Originally posted by Peter den Haan: There is zero, zip, zilch performance difference. Upon entry into a method, a stack frame is allocated that is large enough for ALL variables declared in any scope within the method. Compile both your code samples and use javap -c to decompile the class files. The compiler generates completely identical code for both. It doesn't get more conclusive than that
Hell, I would have bet that it is that way - that is why I was surprised by the benchmark... :roll: Fascinating - I changed the benchmark a little bit, and now it shows absolutely the same performance for both loops:
Seems as if Hotspot had some problems with the first loop in the former benchmark?!?
Anonymous
Ranch Hand
Joined: Nov 22, 2008
Posts: 18944
posted
0
Originally posted by Peter den Haan: There is zero, zip, zilch performance difference. Upon entry into a method, a stack frame is allocated that is large enough for ALL variables declared in any scope within the method.
You're absolutely right of course. Every self respecting compiler is able to calculate the union of all stackframe snapshots an figure the maximum total size of that frame including the ofsets of the local variables stored therein. James Gosling et. al. were clever enough to demand that local variables must be initialized either in their declaration statement or before their first usage as an rvalue, so no additional 'setup stuff' is needed when a variable is being declared. kind regards
Sebastian Krzyzanowski
Greenhorn
Joined: Jun 17, 2002
Posts: 16
posted
0
Thanks a lot for all suggestions hints and benchmarks. Mainly I was afraid that declaring a bunch of variables inside a loop which is traversed some thousend times could result in serious memory (and further performance) loss, since new memory is allocated (each time) - possibly before the old one can be freed by garbage collection... Even with allocating a large enough stackframe first, I would assume that the allocated size differs largely for the both possibilities... Or are local variables declared inside a loop (and hence the memory of these variables) really reused?
Ilja Preuss
author
Sheriff
Joined: Jul 11, 2001
Posts: 14112
posted
0
Originally posted by Sebastian Krzyzanowski:
Or are local variables declared inside a loop (and hence the memory of these variables) really reused?
Yes - and they are not garbage collected, because they aren't stored on the heap, but on the stack. The memory is allocated at method entry and deallocated at method exit.
Peter den Haan
author
Ranch Hand
Joined: Apr 20, 2000
Posts: 3252
posted
0
Originally posted by Sebastian Krzyzanowski: Even with allocating a large enough stackframe first, I would assume that the allocated size differs largely for the both possibilities...
As I said the generated code is identical for both. Blimey, just use javap -c, it's part of your JDK, just see for yourself... - Peter