回答:
2つの要素のいずれかで要素を反復すると、要素がソートされます。とは違いDictionary<T,V>
ます。
MSDNは違いアドレスSortedList<T,V>
とをSortedDictionary<T,V>
:
SortedDictionary(TKey、TValue)ジェネリッククラスは、O(log n)を取得するバイナリ検索ツリーです。ここで、nはディクショナリ内の要素の数です。この点で、それはSortedList(TKey、TValue)ジェネリッククラスに似ています。2つのクラスには同様のオブジェクトモデルがあり、両方にO(log n)取得があります。2つのクラスが異なるのは、メモリの使用と挿入および削除の速度です。
SortedList(TKey、TValue)は、SortedDictionary(TKey、TValue)よりも少ないメモリを使用します。
SortedDictionary(TKey、TValue)は、ソートされていないデータの挿入および削除操作が高速です:SortedList(TKey、TValue)のO(n)ではなく、O(log n)。
リストが並べ替えられたデータから一度に入力される場合、SortedList(TKey、TValue)はSortedDictionary(TKey、TValue)より高速です。
SortedList
(キーによる検索でSortedDictionary
はなく)インデックスで検索できることと、できないことです。
辞書の違いについて触れておきます。
上の図はDictionary<K,V>
、すべての場合でSorted
アナログよりも高速か高速であることを示していますが、要素の順序が必要な場合、たとえばそれらを印刷する場合Sorted
は、1つが選択されます。
Src:http : //people.cs.aau.dk/~normark/oop-csharp/html/notes/collections-note-time-complexity-dictionaries.html
Immutable
、これらのディクショナリのバージョン間で選択した場合、Sorted
バージョンは実際にはソートされていないものよりも40〜50%高速であることが多いことに注意してください(まだO(log(n))
ですが、操作ごとに著しく高速です)。 。ただし、入力がどのようにソートされるかによって、タイミングが異なる場合があります。stackoverflow.com/a/30638592/111575を
パフォーマンステストの結果をまとめると、SortedList対SortedDictionary対Dictionary対Hashtableであり、さまざまなシナリオでの最高から最低までの結果です。
メモリ使用量:
SortedList<T,T>
Hashtable
SortedDictionary<T,T>
Dictionary<T,T>
挿入:
Dictionary<T,T>
Hashtable
SortedDictionary<T,T>
SortedList<T,T>
検索操作:
Hashtable
Dictionary<T,T>
SortedList<T,T>
SortedDictionary<T,T>
foreachループ操作
SortedList<T,T>
Dictionary<T,T>
Hashtable
SortedDictionary<T,T>
Collection
ニーズがなければsorted
、あなたは忘れることができHashtable
そしてDictionary
:あなたはワンショットであなたのコレクションを取り込む場合- > SortedListのために行くが、あなたが予想される場合には、多くの場合に必要になります.Add
し、.Remove
アイテム- > SortedDictionaryのために行きます。
sorted
意味を明確にする必要がありFor Each MyItem in Collection
ます。最初.Add
にアイテムを編集した順序で処理されるのではなく、a sorted
Collection
がKey
値のクリテロン(で定義されているIComparer
)に従って順序で処理します。たとえば、キーが文字列の場合、コレクションはデフォルトでキーのアルファベット順で処理されますが、カスタムの並べ替えルールをいつでも定義できます。
提案された回答はパフォーマンスに焦点を当てていることがわかります。以下の記事では、パフォーマンスに関する新しい情報は提供されていませんが、根本的なメカニズムについて説明しています。またCollection
、質問で言及されている3つのタイプに焦点を合わせていないが、System.Collections.Generic
名前空間のすべてのタイプに対応していることに注意してください。
辞書はおそらく最もよく使われる連想コンテナクラスです。辞書は隠されたハッシュテーブルを使用するため、連想検索/挿入/削除の最高速クラスです。キーはハッシュされるため、キータイプはGetHashCode()およびEquals()を適切に実装するか、構築時にディクショナリに外部IEqualityComparerを提供する必要があります。ディクショナリ内のアイテムの挿入/削除/ルックアップ時間は、一定の時間-O(1)-で償却されます。つまり、ディクショナリがどれほど大きくても、何かを見つけるのにかかる時間は比較的一定です。これは、高速ルックアップに非常に適しています。唯一の欠点は、ハッシュテーブルを使用するという性質上、辞書が順序付けされていないことです。辞書の項目を順番に簡単にたどることはできません。
SortedDictionaryは、使用法はディクショナリに似ていますが、実装が大きく異なります。SortedDictionaryは、キー順に項目を維持するために、カバーの下にバイナリツリーを使用しています。並べ替えの結果、キーに使用される型は、キーが正しく並べ替えられるように、IComparableを正しく実装する必要があります。ソートされたディクショナリは、アイテムを順番に維持する機能と少しのルックアップ時間を交換します。したがって、ソートされたディクショナリの挿入/削除/ルックアップ時間は対数-O(log n)です。一般的に言えば、対数時間を使用すると、コレクションのサイズを2倍にすることができ、アイテムを見つけるために追加の比較を1回実行するだけで済みます。高速なルックアップが必要であるが、キーによる順序でコレクションを維持できるようにしたい場合は、SortedDictionaryを使用します。
SortedListは、汎用コンテナ内の他のソートされた連想コンテナクラスです。ここでも、SortedDictionaryと同様に、SortedList はキーを使用してキーと値のペアをソートします。ただし、SortedDictionaryとは異なり、SortedList内のアイテムは、アイテムの並べ替えられた配列として格納されます。。これは、挿入と削除が線形であることを意味します-O(n)-アイテムを削除または追加すると、リスト内のすべてのアイテムが上下にシフトする場合があるためです。ただし、SortedListはバイナリ検索を使用して、キーでリスト内の任意の項目を見つけることができるため、ルックアップ時間はO(log n)です。では、なぜこれをしたいのでしょうか?答えは、SortedListを事前にロードする場合、挿入は遅くなりますが、配列のインデックス付けはオブジェクトリンクをたどるよりも高速であるため、検索はSortedDictionaryよりもわずかに高速です。繰り返しますが、高速なルックアップが必要で、コレクションをキー順に管理したい場合や、挿入や削除がほとんど行われない場合にこれを使用します。
私はすべてが正しくできていないと確信しているので、フィードバックは大歓迎です。
n
です。辞書
記憶
KeyArray(n) -> non-sorted array<pointer>
ItemArray(n) -> non-sorted array<pointer>
HashArray(n) -> sorted array<hashvalue>
追加
HashArray(n) = Key.GetHash
(1)を追加KeyArray(n) = PointerToKey
(1)を追加ItemArray(n) = PointerToItem
(1)を追加削除する
For i = 0 to n
、i
どこを見つけるHashArray(i) = Key.GetHash
#O(log n)(ソートされた配列)HashArray(i)
(n)(ソートされた配列)を削除KeyArray(i)
(1)を削除ItemArray(i)
(1)を削除アイテムを入手する
For i = 0 to n
、i
どこを見つけるHashArray(i) = Key.GetHash
#O(log n)(ソートされた配列)ItemArray(i)
ループスルー
For i = 0 to n
、戻る ItemArray(i)
SortedDictionary
記憶
KeyArray(n) = non-sorted array<pointer>
ItemArray(n) = non-sorted array<pointer>
OrderArray(n) = sorted array<pointer>
追加
KeyArray(n) = PointerToKey
(1)を追加ItemArray(n) = PointerToItem
(1)を追加For i = 0 to n
、i
どこを見つけるKeyArray(i-1) < Key < KeyArray(i)
(を使用してICompare
)#O(n)OrderArray(i) = n
(n)(ソートされた配列)を追加削除する
For i = 0 to n
、i
どこでKeyArray(i).GetHash = Key.GetHash
#O(n)を見つけるKeyArray(SortArray(i))
(n)を削除ItemArray(SortArray(i))
(n)を削除OrderArray(i)
(n)(ソートされた配列)を削除アイテムを入手する
For i = 0 to n
、i
どこでKeyArray(i).GetHash = Key.GetHash
#O(n)を見つけるItemArray(i)
ループスルー
For i = 0 to n
、戻る ItemArray(OrderArray(i))
SortedList
記憶
KeyArray(n) = sorted array<pointer>
ItemArray(n) = sorted array<pointer>
追加
For i = 0 to n
、i
場所を見つけるKeyArray(i-1) < Key < KeyArray(i)
(を使用してICompare
)#O(log n)KeyArray(i) = PointerToKey
(n)を追加ItemArray(i) = PointerToItem
(n)を追加削除する
For i = 0 to n
、i
どこを見つけるKeyArray(i).GetHash = Key.GetHash
#O(log n)KeyArray(i)
(n)を削除ItemArray(i)
(n)を削除アイテムを入手する
For i = 0 to n
、i
どこを見つけるKeyArray(i).GetHash = Key.GetHash
#O(log n)ItemArray(i)
ループスルー
For i = 0 to n
、戻る ItemArray(i)
@Levによって提示された各ケースにパフォーマンススコアを割り当てようとして、次の値を使用しました。
結果は(高い=より良い)です。
Dictionary: 12.0
SortedDictionary: 9.0
SortedList: 6.5
もちろん、すべてのユースケースは特定の操作により大きな重みを与えます。