0

In the concurrent environment, and only get object from map, no put. The HashMap and ConcurrentHashMap, Whose performance is better in jdk 1.6.

In my limited experience with these two map, ConcurrentHashMap consists of segments. And when get an object from it, it needs at least two locate action. First is to find the correct segment and next is to find the correct table while HashMap only needs locate once. Further more, in my opinion when we just get object from map, there is no race of lock. So I think in jdk 1.6, there is no doubt that HashMap will performance better than ConcurrentHashMap in concurrent environment when just get object from it.

But unfortunately, The test result doesn't support my argument.

Here is my test code.

public static void main(String[] args) throws InterruptedException {
        final Map<Integer, Integer> hashMap = new HashMap<Integer, Integer>();
        final Map<Integer, Integer> concurrentHashMap = new ConcurrentHashMap<Integer, Integer>();
        init(hashMap);
        init(concurrentHashMap);
        final Random random = new Random(System.currentTimeMillis());
        final CountDownLatch latch1 = new CountDownLatch(100);
        long start1 = System.nanoTime();
        for (int i = 0; i < 100; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int count = 0; count < 10000; count++) {
                        hashMap.get(random.nextInt(100));
                    }
                    latch1.countDown();
                }
            }).start();
        }
        latch1.await();
        long end1 = System.nanoTime();
        System.out.println("hashMap : " + (end1 - start1));


        final CountDownLatch count2 = new CountDownLatch(100);
        long start2 = System.nanoTime();
        for (int i = 0; i < 100; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    for (int count = 0; count < 10000; count++) {
                        concurrentHashMap.get(random.nextInt(100));
                    }
                    count2.countDown();
                }
            }).start();
        }
        count2.await();
        long end2 = System.nanoTime();
        System.out.println("concurrentHashMap : " + (end2 - start2));

    }

    private static void init(Map<Integer, Integer> map) {
        for (int i = 0; i < 100; i++) {
            map.put(i, i);
        }
    }

The last three outputs are:

hashMap : 78448168
concurrentHashMap : 68820282

hashMap : 87819463
concurrentHashMap : 76098734

hashMap : 87901572
concurrentHashMap : 71385562

Then I test the performance in single thread environment.(Repeat random get object from map 10000 times.)

Here is my test result.

enter image description here

The average time of HashMap is 4982047 ns while ConcurrentHashMap is 3150367 ns.

The result indicates that ConcurrentHashMap performance better than HashMap even in single thread environment.

I'm really confused.Is there something that I understand wrong? Or just my test code isn't rigorous?

chaos
  • 1,359
  • 2
  • 13
  • 25
  • 1
    Your test code is wrong. `HashMap` being simpler is faster, but that only works with immutable maps so it's not exactly a huge issue. – Kayaman Dec 09 '17 at 07:12
  • If your map doesn't *require* synchronization of any kind, then using `HashMap` is fine. It will be faster. `ConcurrentHashMap` is for cases where you *do* need to synchronize (for correctness in a multi-thread application). – Stephen C Dec 09 '17 at 07:32

0 Answers0