Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is creating a HashMap faster than creating an Object[]?

I've tried to build my own Map to increase the performance for a special environment, and I realized something pretty interesting: Creating a new Hashmap<Integer,String>(2000) is faster than new Object[2000] - no matter in which order I execute these commands. That's pretty confusing to me, esp. because the Hashmap constructor contains a table = new Entry[capacity], according to this. Is there something wrong with my testbench?

public static void test(int amm){ //amm=1_000_000     Map<Integer,String> m1 = null;     Object[] arr = null;      long time = System.nanoTime();     for(int i = 0; i < amm; i++){         m1 = new HashMap<Integer, String>(2000);     }     System.out.println("m1: " + (System.nanoTime() - time)); //m1: 70_455_065      time = System.nanoTime();     for(int i = 0; i < amm; i++){         arr = new Object[2000];     }     System.out.println("arr: " + (System.nanoTime() - time)); //arr: 1_322_473_803 } 

I'd love to see the results of testing on another computer. I've got no clue why creating a HashMap is 10 times faster than creating a Object[].

like image 358
alex berne Avatar asked Jul 14 '15 23:07

alex berne


People also ask

Why is HashMap faster?

The reason that HashMap is faster than HashSet is that the HashMap uses the unique keys to access the values. It stores each value with a corresponding key and we can retrieve these values faster using keys during iteration. While HashSet is completely based on objects and therefore retrieval of values is slower.

Why HashMap is faster than other map?

HashMap, being a hashtable-based implementation, internally uses an array-based data structure to organize its elements according to the hash function. HashMap provides expected constant-time performance O(1) for most operations like add(), remove() and contains(). Therefore, it's significantly faster than a TreeMap.

Which is faster set or HashMap?

HashMap is faster than HashSet because the values are associated to a unique key. In HashSet , member object is used for calculating hashcode value which can be same for two objects so equals() method is used to check for equality.

Why is HashMap efficient?

For each element, HashMap computes the hash code and puts the element in the bucket associated with that hash code. Because non-equal objects can have the same hash codes (a phenomenon called hash code collision), buckets can grow in size. The bucket is actually a simple linked list.


1 Answers

If you look at the implementation of HashMap, the constructor looks like:

public HashMap(int initialCapacity, float loadFactor) {     if (initialCapacity < 0)         throw new IllegalArgumentException("Illegal initial capacity: " +                                            initialCapacity);     if (initialCapacity > MAXIMUM_CAPACITY)         initialCapacity = MAXIMUM_CAPACITY;     if (loadFactor <= 0 || Float.isNaN(loadFactor))         throw new IllegalArgumentException("Illegal load factor: " +                                            loadFactor);      this.loadFactor = loadFactor;     threshold = initialCapacity;     init(); } 

And init() looks like:

/**  * Initialization hook for subclasses. This method is called  * in all constructors and pseudo-constructors (clone, readObject)  * after HashMap has been initialized but before any entries have  * been inserted.  (In the absence of this method, readObject would  * require explicit knowledge of subclasses.)  */ void init() { } 

So initialCapacity doesn't actually get used to create an array. Where does it get used? Look at the put() method.

public V put(K key, V value) {     if (table == EMPTY_TABLE) {         inflateTable(threshold);     }     // hidden }  

When doing a put, the array is actually created. I didn't show inflateTable() but it does some math and initializes the array.

like image 97
Amir Raminfar Avatar answered Oct 13 '22 10:10

Amir Raminfar