Hope I can get some comments on this. If I need to create a HashMap, and I know that it will only have a fixed number of elements, say 2, will I run into any problems if I create a HashMap like -
The idea of course is to have the HashMap initialized with the exact capacity needed to save space, and making sure that no rehashing would be needed.
May be I should not be worrying about it, but I need to create a large number of HashMap(s) that are used only once i.e. it is populated with a fixed number of values at once place, those are retrieved at another place in the code and then the HashMap discarded, and this would be a simple-to-do optimization at this stage.
I did not consider a TreeMap, because I dont need to maintain any order on the elements. Will TreeMap be a better choice in this case? Could you please explain that. Any references on the net?
A bit more detail about the requirements. Basically, I am using a Map in a generic interface to separate HTTP related tasks from the business logic. A frequently called method returns a Map, all objects in the map are set as HttpRequest attributes by a controller class, and the map discarded. A bit like Spring framework interfaces for MVC support.
First, have you considered that you may be optimizing prematurely? I love to optimize too, but I've learned to back off until I've verified that there is a bottleneck and where. You may be working really hard to shave off less than a millisecond.
Second, realize that if you don't really know how HashMap works, you might be causing a performance problem. To wit, if you size the Map with 2 slots and both objects happen to hash to the same slot, you are causing harm:
You are wasting a slot.
The slot you are using has to hold a List instead of a single element.
Worst of all, every get requires doing equals() comparisons on each key on top of using the hash.
And for what? To save 16 or 32 bytes? You've lost any gain by forcing a list in the used slot. Remember that the new JVMs are very good at creating lots of tiny short-lived objects by segretating its heap into zones (like the Green Zone and the Spin Zone, only better!).
My advice would be to leave it with normal HashMaps, profile, and see if you have a problem. Then optimize the true problem.
Yup, that is exactly what I was trying to find out. I had a faint idea about that problem, but wasnt sure of the exact details. Following your advice, I am going to leave the HashMap with default settings. Thanks.
I had similar questions about creating an ArrayList with a specific initial capacity, but in that case too, it is probabely safer to stick to the default constructor. From Java docs for ArrayList-
As elements are added to an ArrayList, its capacity grows automatically. The details of the growth policy are not specified beyond the fact that adding an element has constant amortized time cost
Any comments on that?
Joined: Aug 07, 2003
Well this may sound like I'm a bit nuts, but in the case of ArrayList I presize when I can. For one thing reading the source code for both classes will leave you with one certain impression: ArrayList is much easier to understand. I've also written more ArrayList implementations in various languages than HashMaps, so I know them very well.
If you're going to add five elements, the benefit of sticking that in code may not be as high as if you're adding 10,000. The higher the number of elements, the great the penalty for being wrong. If you presize it with five and then add seven elements, who cares? You'll pay the penalty of a single reallocation. Of course, if you leave it without an argument you'll get 20 slots (last I checked) and "waste" 42 bytes. Again, you need to weigh the costs of stressing over it.
There are cases where it's a no brainer, though.See, now it's just silly not to presize that ArrayList since using "teams.size()" will always be correct no matter how many elements it has. Okay, I haven't looked in a while, so maybe ArrayList will choke on 0, so you can test for that at the start and return Collections.EMPTY_LIST instead (as long as the caller isn't planning to modify the list). You should be doing that anyway as long as you're micro-optimizing.
That makes perfect sense. I am also not in favour of preoptimizing, unless it is perfectly clear that there would be no hidden issues.
I just had a quick look at ArrayList source, the default size is set to 10. And it resizes when the current index becomes greater than the internal array length, at which point it resizes the array to (current_length * 1.5) + 1.
I think I am going to stick to the default constructor for very small lists. Thanks a lot for your help.