I did some profiling on my application and one of the results turned out that about 18% of memory on the heap is used by objects of type Double
. It turns out these objects are the values in Map
s, where I cannot use the primitive type.
My reasoning is that the primitive type of double
consumes less memory than it's object Double
. Is there a way to have a map like data structure, that would accept any type as key and a primitive double
as values?
Main operations would be:
Typical maps that I have are:
HashMap<T, HashMap<NodeData<T>, Double>> graph
HashMap<Point2D, Boolean> onSea
(though not a double value)ConcurrentHashMap<Point2D, HashMap<Point2D, Double>>
All used with Java 8.
Addendum
I am mainly not interested in frameworks that have a solution to these type of maps, but on what has to be considered when addressing these issues. If you want, what are the concepts/ideas/approaches behind any such framework. Or the solution may be also on another level, where the maps are replaced with objects following a certain pattern like @Ilmari Karonen pointed out in his answer.
Eclipse Collections has object and primitive maps and has Mutable and Immutable versions for both.
MutableObjectDoubleMap<String> doubleMap = ObjectDoubleMaps.mutable.empty();
doubleMap.put("1", 1.0d);
doubleMap.put("2", 2.0d);
MutableObjectBooleanMap<String> booleanMap = ObjectBooleanMaps.mutable.empty();
booleanMap.put("ok", true);
ImmutableObjectDoubleMap<String> immutableMap = doubleMap.toImmutable();
Assert.assertEquals(doubleMap, immutableMap);
A MutableMap
can be used as a factory for an ImmutableMap
in Eclipse Collections by calling toImmutable
as I have done in the example above. Both mutable and immutable maps share a common parent interface, which in the case of the MutableObjectDoubleMap
and ImmutableObjectDoubleMap
above, is named ObjectDoubleMap
.
Eclipse Collections also has synchronized and unmodifiable versions for all mutable containers in the library. The following code will give you a synchronized view wrapped around the primitive maps.
MutableObjectDoubleMap<String> doubleMap =
ObjectDoubleMaps.mutable.<String>empty().asSynchronized();
doubleMap.put("1", 1.0d);
doubleMap.put("2", 2.0d);
MutableObjectBooleanMap<String> booleanMap =
ObjectBooleanMaps.mutable.<String>empty().asSynchronized();
booleanMap.put("ok", true);
This performance comparison of large maps was published a couple of years ago.
Large HashMap overview: JDK, FastUtil, Goldman Sachs, HPPC, Koloboke, Trove – January 2015 version
GS Collections has since been migrated to the Eclipse Foundation and is now Eclipse Collections.
Note: I am a committer for Eclipse Collections.