Saturday, May 22, 2010

Hashtable vs. HashMap and a little thing called Entry

This was just to check if there are any real performance issues between Hashtable, HashMap and Collections.synchronizedMap(map), and as it turns out... it ain't that that bad... and even though the Hashtable is synchronized it still reads faster.

Something else to note, iterating via the entry set far out performs a regular get.
So when sequentially going through a map it's probably the way to go.

Hashtable

Does NOT allow null in either the key or the value. Will throw java.lang.NullPointerException.
It is synchronized.

HashMap

Allows null in either the key or the value.
It is NOT synchronized.

package bob.blog;

import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Map.Entry;

/**
 * The Class HashtableVsHashmap.
 */
public class HashtableVsHashmap {

    private static Map< String, String > map;

    private static String bob = new String("bob");

    private static final int iter = 500000;

    private static long start = 0;

    private static long end = 0;

    /**
     * The main method.
     * 
     * @param args the arguments
     */
    public static void main(final String[] args) {

 hashtablePerf();
 hashmapPerf(false);
 hashmapPerf(true);
    }

    /**
     * Hashmap perf.
     */
    private static void hashmapPerf(final boolean syncd) {

 // HashMap
 map = new HashMap< String, String >();
 if (syncd) {
     map = Collections.synchronizedMap(map);
 }
 start = System.currentTimeMillis();
 for (int i = 0; i < iter; i++) {
     map.put(bob + i, bob);
 }
 map.put(null, null);
 end = System.currentTimeMillis();
 System.out.println("Inserting HashMap: " + (end - start) + " ms - Synchronized: " + syncd);

 start = System.currentTimeMillis();
 for (int i = 0; i < iter; i++) {
     map.get(bob + i);
 }

 end = System.currentTimeMillis();
 System.out.println("Reading HashMap: " + (end - start) + " ms - Synchronized: " + syncd);
 
 start = System.currentTimeMillis();
 for(Entry< String, String > e : map.entrySet()){
     String val = e.getValue();
 }
 end = System.currentTimeMillis();
 System.out.println("Reading HashMap by Entry: " + (end - start) + " - Synchronized: " + syncd);
    }

    /**
     * Hashtable perf.
     */
    private static void hashtablePerf() {
 // Hashtable
 map = new Hashtable< String, String >();
 start = System.currentTimeMillis();
 for (int i = 0; i < iter; i++) {
     map.put(bob + i, bob);
 }
 end = System.currentTimeMillis();
 System.out.println("Inserting Hashtable: " + (end - start) + " ms");

 start = System.currentTimeMillis();
 for (int i = 0; i < iter; i++) {
     map.get(bob + i);
 }
 end = System.currentTimeMillis();
 System.out.println("Reading Hashtable: " + (end - start) + " ms");

 start = System.currentTimeMillis();
 for(Entry< String, String > e : map.entrySet()){
     String val = e.getValue();
 }
 end = System.currentTimeMillis();
 System.out.println("Reading Hashtable by Entry: " + (end - start) + " ms");
 
    }

}

Output:
Inserting Hashtable: 640 ms
Reading Hashtable: 172 ms
Reading Hashtable by Entry: 31 ms
Inserting HashMap: 610 ms - Synchronized: false
Reading HashMap: 265 ms - Synchronized: false
Reading HashMap by Entry: 47 - Synchronized: false
Inserting HashMap: 625 ms - Synchronized: true
Reading HashMap: 282 ms - Synchronized: true
Reading HashMap by Entry: 46 - Synchronized: true

2 comments:

Popular Posts

Followers