Java Concurrency: Are "get(Key) for HashMap and ConcurrentHashMap equal in performance?

后端 未结 3 909
情话喂你
情话喂你 2021-01-19 21:38

Are get(Key) method calls for a a standard HashMap and a ConcurrentHashMap equal in performance when no modifications happen for the u

相关标签:
3条回答
  • 2021-01-19 21:58

    According to the ConcurrentHashMap API, there is no locking for retrieval methods. So, I'd say they are equal in performance.

    0 讨论(0)
  • 2021-01-19 22:00

    You could look at the source code. (I'm looking at JDK 6) HashMap.get() is pretty simple:

    public V get(Object key) {
            if (key == null)
                return getForNullKey();
            int hash = hash(key.hashCode());
            for (Entry<K,V> e = table[indexFor(hash, table.length)];
                 e != null;
                 e = e.next) {
                Object k;
                if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
                    return e.value;
            }
            return null;
        }
    

    Where hash() does some extra shifting and XORing to "improve" your hash code.

    ConcurrentHashMap.get() is a bit more complex, but not a lot

    public V get(Object key) {
        int hash = hash(key.hashCode());
        return segmentFor(hash).get(key, hash);
    }
    

    Again, hash() does some shifting and XORing. setMentFor(int hash) does a simple array lookup. The only complex stuff is in Segment.get(). But even that doesn't look like rocket science:

    V get(Object key, int hash) {
       if (count != 0) { // read-volatile
          HashEntry<K,V> e = getFirst(hash);
          while (e != null) {
             if (e.hash == hash && key.equals(e.key)) {
                V v = e.value;
                if (v != null)
                   return v;
                return readValueUnderLock(e); // recheck
              }
              e = e.next;
          }
     }
      return null;
    }
    

    The one place where is gets a lock is readValueUnderLock(). The comments say that this is technically legal under the memory model but never known to occur.

    Overall, looks like the code is pretty similar for both. Just a bit better organized in ConcurrentHashMap. So I'd guess that the performance is similar enough.

    That said, if puts really are extremely rare, you could consider implementing a "copy on write" type of mechanism.

    0 讨论(0)
  • 2021-01-19 22:08

    You're asking the wrong question.

    If you need concurrency, you need it no matter the performance impact.

    A correctly behaving program almost always ranks more highly than a faster program. I say "almost always" because there may be business reasons to release software with bugs rather than holding back until the bugs are fixed.

    0 讨论(0)
提交回复
热议问题