values()
関数を通過するためのHashMap
とLinkedHashMap
の間にパフォーマンスの違いはありますか?
LinkedHashMap
は、nextEntry
のIterator
実装が優れているため、トラバーサルの速度を上げる必要があると思います
これが理由です:
values
の実装から段階的に見ていきましょう。HashMap
のvalues
実装はこれです:
_ public Collection<V> values() {
Collection<V> vs = values;
return (vs != null ? vs : (values = new Values()));
}
_
LinkedHashMap
はHashMap
から拡張され、同じ実装を継承します。
違いは、両方のIterator
のValues
実装にあります。
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
メソッドを確認してください。
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があり、今後のコードで使用する予定です。
それはほとんど問題ではありません。問題は、何が必要かということです。要素の順序に関連がある場合は、LinkedHashMap
を使用する必要があります。それ以外の場合は必要ないので、HashMap
を使用します。
最良のアドバイスは「試してみることを恐れないでください」ですが、私はそれらが非常に似ていると確信しています。値セットのゲッターはO(1)であり、各反復子ステップも同様です。リンクリストを反復することはハッシュバケットを反復することと同じくらい簡単です。リンクされたリスト。
はい、HashMap
とLinkedHashMap
のすべての反復で得られるのと同じパフォーマンスの違いがあります。HashMap
は、エントリの数とサイズの合計に比例して時間がかかります。ハッシュテーブル、およびLinkedHashMap
は、エントリの数に比例して時間がかかります。
私はUnitTestでみました、values()を10000回繰り返しました、ミリ秒:806対902。それはほとんど同じです。