views:

120

answers:

2

Which of the following would be more optimal on a Java 6 HotSpot VM?

final Map<Foo,Bar> map = new HashMap<Foo,Bar>(someNotSoLargeNumber);    
for (int i = 0; i < someLargeNumber; i++)
{
  doSomethingWithMap(map);
  map.clear();
}

or

final int someNotSoLargeNumber = ...;
for (int i = 0; i < someLargeNumber; i++)
{
  final Map<Foo,Bar> map = new HashMap<Foo,Bar>(someNotSoLargeNumber);      
  doSomethingWithMap(map);
}

I think they're both as clear to the intent, so I don't think style/added complexity is an issue here.

Intuitively it looks like the first one would be better as there's only one 'new'. However, given that no reference to the map is held onto, would HotSpot be able to determine that a map of the same size (Entry[someNotSoLargeNumber] internally) is being created for each loop and then use the same block of memory (i.e. not do a lot of memory allocation, just zeroing that might be quicker than calling clear() for each loop)?

An acceptable answer would be a link to a document describing the different types of optimisations the HotSpot VM can actually do, and how to write code to assist HotSpot (rather than naive attmepts at optimising the code by hand).

+7  A: 

Don't spend your time on such micro optimizations unless your profiler says you should do it. In particular, Sun claims that modern garbage collectors do very well with short-living objects and new() becomes cheaper and cheaper

Dmitry
It's going to be moving the map from survivor spaces and into the tenured generation that is likely to cause most problems. So the new every iteration is a likely win (and nicer code). Unlikely to be worth worrying about.
Tom Hawtin - tackline
It's not so much that I'm trying to optimise code, I just wanted to write it correctly first time, and given that they both accomplish the same thing I thought I'd check if there was any way I could help the JVM. I think the second option is the nicer code, since the scope of the map is the loop, and as the article says, even if the JVM can't optimise the code now, it may well be possible in the future.Good article BTW.
SimonC
+1  A: 

That's a pretty tight loop over a "fairly large number", so generally I would say move the instantiation outside of the loop. But, overall, my guess is you aren't going to notice much of a difference as I am willing to bet that your doSomethingWithMap will take up the majority of time to allow the GC to catch up.

MarkPowell