ConcurrentHaspMap vs HashTable execution time

118 Views Asked by At

In literature you can find out, that ConcurrentHashMap is much faster than HashTable. I'm just wondering why the following code doesn't show that.

In following code some numbers are filled both in ConcurrentHashMap (chm) and HashTable (ht). There are two equivalent Callable (one for chm and the other for ht), which are doing the same operation on chm or ht elements and return execution time in ms.

I've get execution time for ht less in a half that for chm.

public class ConcurrentHashMapDemo {

    static ConcurrentHashMap<Long, Double> chm;
    static Hashtable<Long, Double> ht;
    int result1;
    int result2;
    static long numbers = 1000000;

    public ConcurrentHashMapDemo(){
        chm = new ConcurrentHashMap<>();
        ht = new Hashtable<>();
        result1=0;
        result2=0;
    }
    // just do some operation with map or table elements
    private class Th1 implements Callable<Integer>{
        public Integer call(){
            long base = System.currentTimeMillis();
            for(Entry<Long, Double> e: chm.entrySet()){
                result1+=e.getKey();
                result1+=(int)(e.getValue()*10);
            }
            long time = System.currentTimeMillis();
            return (int)(time-base);
        }
    }

    private class Th2 implements Callable<Integer>{
        public Integer call(){
            long base = System.currentTimeMillis();
            for(Entry<Long, Double> e: ht.entrySet()){
                result2+=e.getKey();
                result2+=(int)(e.getValue()*10);
            }
            long time = System.currentTimeMillis();
            return (int)(time-base);
        }
    }

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        ConcurrentHashMapDemo chmd = new ConcurrentHashMapDemo();
        for(long i=0;i<numbers;i++){
            chm.put((Long)i, Math.sqrt(i));
            ht.put((Long)i, Math.sqrt(i));
        }
        ExecutorService ex = Executors.newCachedThreadPool();
        try {
            Future<Integer>s11 = ex.submit(chmd.new Th1());
            System.out.println("chm "+s11.get());   // appr. 220
            Thread.sleep(1000);
            Future<Integer>s21 = ex.submit(chmd.new Th2());
            System.out.println("ht "+s21.get());    // appr. 110
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
        ex.shutdown();
    }
}
1

There are 1 best solutions below

0
On

You're comparing apples to oranges here.

ConcurrentHashMap is concurrent - which means that you can use it in more threads concurrently.

Hashtable is synchronized(some methods for working with it are synchronized - get/put/clear...) -> operations with it are mutually exclusive. Be careful that iterator is not thread safe and therefore it may (and may not - memory visibility) throw ConcurrentModificationException if you try to modify it concurrently when iterating it in some other thread.

You compare performance of iteration over maps in a single thread (each map will run in one thread). Then Hashtable is faster because its implementation is much simpler (it isn't thread safe, it doesn't support concurrent modifications etc.).

If you would create a different benchmark with concurrent modification/access to the maps you would find out that ConcurrentHashMap is faster (because it is concurrent :-) and Hashtable is not).