I have a program working on enormous data sets. The objects are best stored on hash implemented containers since the program keeps seeking for objects in the container.
The first idea was to use HashMap since the methods get and remove of this container are more suitable to the uses I need.
But, I came to see the use of HashMap is pretty memory consumable which is a major problem, so i thought switching to HashSet will be better because it only uses <E>
, and not <K,V>
per element, but when I looked at the implementation i learned it uses an underlying HashMap! this means it wont save any memory!
So this is my questions:
Is there any other Hash based containers which will be significantly less memory consumables?
update
As requested in the comments I will extend a bit on my program, the hashMap is meant to hold a pair of other objects, and some numeric value - a float- calculated from them. along the way it extracts some of them and enters new pairs. Given a pair it needs to ensure it doesnt hold this pair or to remove it. The mapping can be done using the float value or the hashCode
of the pair object.
Additionally when i say "enormous data sets" I am talking about ~ 4*10^9 objects
HashMap is faster/ than HashSet because values are associated with a unique key. HashSet is slower than HashMap because the member object is used for calculating hashcode value, which can be same for two objects. Only one object is created during the add operation.
Hashmap is the implementation of Map interface. Hashset on other hand is the implementation of set interface. Hashmap internally do not implements hashset or any set for its implementation. Hashset internally uses Hashmap for its implementation.
Remember, HashMap can not have duplicate keys. Behind the scene HashSet uses a HashMap . When you attempt to add any object into a HashSet , this entry is actually stored as a key in the HashMap - the same HashMap that is used behind the scene of HashSet .
HashSet uses HashMap for storing its object internally. You must be wondering that to enter a value in HashMap we need a key-value pair, but in HashSet, we are passing only one value.
There are very useful tips on this site about collections performance in java.
HashSet
is built on top of aHashMap< T, Object >
, where value is a singleton ‘present’ object. It means thatthe memory consumption of aHashSet is identical to HashMap
: in order to storeSIZE
values, you need 32 * SIZE + 4 * CAPACITY bytes (plus size of your values). It is definitely not a memory-friendly collection.THashSet could be the easiest replacement collection for a
HashSet
– it implements Set and Iterable, which means you should just update a single letter in the initialization of your set.
THashSet
uses a single object array for its values, so it uses 4 * CAPACITY bytes for storage. As you can see, compared to JDK HashSet, you will save 32 * SIZE bytes in case of the identical load factor, which is a huge improvement.
Also the below image which I took from here can help us keeping something in mind for choosing right collection
Are all my assumptions true?
You are correct that HashSet
is implemented using HashMap
, so you will not save any memory by using HashSet
instead.
If you're creating maps with a large number of elements, you should construct your HashMap
s with an initialCapacity
to the best of your knowledge, in order to prevent repeated rehashing (thus memory thrashing).
Is HashMap memory wasteful? more specifically, what is its overhead for each entry?
No, it's not wasteful. The overhead is an underlying array (size modified by loadFactor
), and an Entry
object for each key-value pair. In addition to storing a key and value, the entry object also stores a pointer to the next entry in a slot (in case two or more entries are occupying the same slot in the underlying array). The default loadFactor of 0.75
keeps the underlying array size at 133% of the number of entries.
Very specifically, the memory overhead for each entry is:
It's very difficult to get much more trim than that for a hash-based collection.
Is HashSet just as wasteful as HashMap?
You will gain no memory efficiency by using HashSet
instead of HashMap
.
Is there any other Hash based containers which will be significantly less memory consumables?
If your keys are primitives (e.g. int
s), there are custom Map
and Set
implementations out there (in third party libraries) which use more memory-efficient data structures.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With