xgb84j
xgb84j

Reputation: 559

HashMap memory efficiency

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:

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

Answers (4)

xgb84j
xgb84j

Reputation: 559

I found a solution that uses around 22 bytes per double array with the following method:

  • Use double[] instead of Double[]
  • I order the data I get by the first layer of keys and I used THashMap from the Trove library. This implementation of HashMap has a compact method that shrinks the size of a HashMap down to exactly the size it needs to hold all elements it has right now. By periodically calling this function I was able to constantly keep the size down.

Upvotes: 0

Hot Licks
Hot Licks

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

Tom
Tom

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

user207421
user207421

Reputation: 310840

Your description is a little confused, but I would:

  1. Use a very high load factor such as 95%.

  2. Make it double[] instead of Double[]

Upvotes: 2

Related Questions