web-dev-qa-db-ja.com

values()の反復におけるHashMapとLinkedHashMapのパフォーマンス

values()関数を通過するためのHashMapLinkedHashMapの間にパフォーマンスの違いはありますか?

30
MBZ

LinkedHashMapは、nextEntryIterator実装が優れているため、トラバーサルの速度を上げる必要があると思います

これが理由です:

valuesの実装から段階的に見ていきましょう。
HashMapvalues実装はこれです:

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

LinkedHashMapHashMapから拡張され、同じ実装を継承します。

違いは、両方のIteratorValues実装にあります。

HashMapの場合、_Java.util.HashMap.HashIterator_から拡張されます

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

LinkedHashMapの場合、_Java.util.LinkedHashMap.LinkedHashIterator_から拡張されます

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

つまりdifferenceは本質的にnextEntry実装に要約されます。

LinkedHashMapの場合はe.afterを呼び出すだけです。ここでeはEntryですが、HashMapの場合、_Entry[]_配列をトラバースして次次.

[〜#〜] update [〜#〜]nextEntry()のコードを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 []は連続したストアではありません。 (間にnull値が存在する可能性があります)。上記のコードを見てみると、現在のコードの隣を指し、Entry []を繰り返して次のコードを見つけます。

しかしこのパフォーマンスの向上は、挿入の代償となると思います。演習として、両方のクラスのaddEntryメソッドを確認してください。

39
Ajay George

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よりもEdgeがあり、今後のコードで使用する予定です。

38
user1016765

それはほとんど問題ではありません。問題は、何が必要かということです。要素の順序に関連がある場合は、LinkedHashMapを使用する必要があります。それ以外の場合は必要ないので、HashMapを使用します。

4
AlexR

最良のアドバイスは「試してみることを恐れないでください」ですが、私はそれらが非常に似ていると確信しています。値セットのゲッターはO(1)であり、各反復子ステップも同様です。リンクリストを反復することはハッシュバケットを反復することと同じくらい簡単です。リンクされたリスト。

2
Marko Topolnik

はい、HashMapLinkedHashMapのすべての反復で得られるのと同じパフォーマンスの違いがあります。HashMapは、エントリの数とサイズの合計に比例して時間がかかります。ハッシュテーブル、およびLinkedHashMapは、エントリの数に比例して時間がかかります。

2
Louis Wasserman

私はUnitTestでみました、values()を10000回繰り返しました、ミリ秒:806対902。それはほとんど同じです。

2
hongtium