Reputation: 559
I am working on a Java web-application that uses one big cascade of hashmaps that looks like this:
HashMap<String, HashMap<String, HashMap<String, Double[]>>>
The construct is once created and then used read-only.
The double array has always exactly two elements. The problem I have is that in the end I use over 160 byte per double array. This is 10 times of what two doubles would use (each 8 byte).
I used Runtime.getRuntime().totalMemory()
to look at memory usage once before the map was created and once after for these measurements.
How do I minimize memory overhead?
There are three possible solutions I consider right now:
Use another data structure or hashmap implementation (which?)
Exactly precalculate the size of each map and set initial capacity to this number + 1 and load factor to 1.0.
Collapse all keys into one String by appending them. This is not very practical for me but absolutely doable. The code would look pretty bad though.
My question now is what is the best way to minimize memory overhead of a hashmap in my case where I create the hashmaps once and then only use them read-only?
Upvotes: 0
Views: 2187
Reputation: 559
I found a solution that uses around 22 bytes per double array with the following method:
Upvotes: 0
Reputation: 47699
Since this sounds like a static table -- not modified -- create the class:
public class MyValues {
String key;
double value1;
double value2;
}
Create the objects and place in an array MyValues[]
, then sort by the key.
Write a binary search algorithm to find values in the table. (This is a very simple piece of code -- 20 lines or so.)
(Use regular HashMaps for the outer layers.)
Upvotes: 0
Reputation: 1221
If you're going to know all of the keys when calling get()
, then I'd suggest creating a new object for the key. Remember to implement equals()
and hashCode()
edit:
Using an object over a concatenated will prevent key collisions with certian combinations. If the strings are "AA", "BB" and "CC", and are concatenated to "AABBCC", then "A", "AB and "BCC" will be concatenated to the same value "AABBCC". Plus it is more readable code.
I have certainly concatenated Strings for keys in the past, but you have to be very careful.
You will lose a little space having this new object, but will save a considerable amount of space by reducing the number of Maps, many of which could be relatively empty.
Upvotes: 1
Reputation: 310840
Your description is a little confused, but I would:
Use a very high load factor such as 95%.
Make it double[]
instead of Double[]
Upvotes: 2