HashMap vs LinkedHashMap 在 value 迭代中的性能()

2022-09-01 05:34:10

遍历函数和遍历函数之间是否存在任何性能差异?HashMapLinkedHashMapvalues()


答案 1

我认为在遍历中必须更快,因为其具有出色的实现性LinkedHashMapnextEntryIterator

原因如下:

让我们从实施中一步一步走。
实现是这样的:valuesHashMapvalues

public Collection<V> values() {
    Collection<V> vs = values;
    return (vs != null ? vs : (values = new Values()));
}

从相同的实现扩展并继承相同的实现。LinkedHashMapHashMap

不同之处在于两者的实现。IteratorValues

因为它从HashMapjava.util.HashMap.HashIterator

private final class ValueIterator extends HashIterator<V> {
    public V next() {
        return nextEntry().value;
    }
}

但对于它延伸到LinkedHashMapjava.util.LinkedHashMap.LinkedHashIterator

private class ValueIterator extends LinkedHashIterator<V> {
    public V next() { return nextEntry().value; }
}

因此,差异基本上可以归结为实现。nextEntry

因为它只是在 e 是 的地方调用 e.after,但是因为在遍历数组以找到下一个下一个数组时需要做一些工作。LinkedHashMapEntryHashMapEntry[]

更新 : 代码 innextEntry()HashMap

final Entry<K,V> nextEntry() {
    if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
    Entry<K,V> e = next;
    if (e == null)
        throw new NoSuchElementException();

    if ((next = e.next) == null) {
        Entry[] t = table;
        while (index < t.length && (next = t[index++]) == null)
            ;
    }
    current = e;
    return e;
}

Entry[] 不是连续的存储区。(两者之间可能存在空值)。如果你看一下上面的代码,它的作用是指向当前代码旁边,并通过迭代 Entry[] 找到下一个代码。

我认为这种性能提升将以插入为代价。查看两个类中的方法作为练习。addEntry


答案 2

我写了一个小的分析程序,创建了100万个键(Integer)与Boolean.TRUE,重复了100次。找到以下内容:

HashMap:-
Create:  3.7sec
Iterate: 1.1sec
Access:  1.5sec
Total:   6.2sec

LinkedHashMap:-
Create:  4.7sec   (30% slower)
Iterate: 0.5sec   (50% faster)
Access:  0.8sec   (50% faster)
Total :  6.0sec

垃圾回收没有这样做会在某种程度上污染数字,但是我认为LinkedHashMap比HashMap更具优势,我将在将来的代码中使用它。