a SortedList<TKey,TValue>
とaの間に実際の実用的な違いはありますSortedDictionary<TKey,TValue>
か?どちらか一方だけを使用するような状況はありますか?
SortedList<TKey,TValue>
1つではなく2つの型パラメーターがあるのはなぜSortedList<T>
ですか?なぜ実装しないのIList<T>
ですか?
a SortedList<TKey,TValue>
とaの間に実際の実用的な違いはありますSortedDictionary<TKey,TValue>
か?どちらか一方だけを使用するような状況はありますか?
SortedList<TKey,TValue>
1つではなく2つの型パラメーターがあるのはなぜSortedList<T>
ですか?なぜ実装しないのIList<T>
ですか?
回答:
はい-パフォーマンス特性は大きく異なります。おそらく、それらを呼び出す方が良いでしょうSortedList
し、SortedTree
そのようなより密接な実装を反映しています。
さまざまな状況でのさまざまな操作のパフォーマンスの詳細については、それぞれのMSDNドキュメント(SortedList
、SortedDictionary
)を参照してください。ここに(SortedDictionary
ドキュメントからの)良い要約があります:
SortedDictionary<TKey, TValue>
ジェネリッククラスは、辞書内の要素の数であるnはO(Nログ)検索とバイナリ検索ツリーです。この点で、SortedList<TKey, TValue>
ジェネリッククラスに似てい ます。2つのクラスには同様のオブジェクトモデルがあり、両方にO(log n)取得があります。2つのクラスが異なるのは、メモリの使用と挿入および削除の速度です。
SortedList<TKey, TValue>
はよりも少ないメモリを使用しますSortedDictionary<TKey, TValue>
。
SortedDictionary<TKey, TValue>
は、並べ替えられていないデータの挿入および削除操作が高速です。O(n)の場合とは対照的に、O(log n)SortedList<TKey, TValue>
。リストが並べ替えられたデータから一度に入力される場合
SortedList<TKey, TValue>
は、よりも高速ですSortedDictionary<TKey, TValue>
。
(SortedList
実際には、ツリーを使用するのではなく、ソートされた配列を維持します。それでも、バイナリ検索を使用して要素を見つけます。)
これが役立つ場合の表形式のビューは次のとおりです...
パフォーマンスの観点:
+------------------+---------+----------+--------+----------+----------+---------+
| Collection | Indexed | Keyed | Value | Addition | Removal | Memory |
| | lookup | lookup | lookup | | | |
+------------------+---------+----------+--------+----------+----------+---------+
| SortedList | O(1) | O(log n) | O(n) | O(n)* | O(n) | Lesser |
| SortedDictionary | n/a | O(log n) | O(n) | O(log n) | O(log n) | Greater |
+------------------+---------+----------+--------+----------+----------+---------+
* Insertion is O(1) for data that are already in sort order, so that each
element is added to the end of the list (assuming no resize is required).
実装の視点:
+------------+---------------+----------+------------+------------+------------------+
| Underlying | Lookup | Ordering | Contiguous | Data | Exposes Key & |
| structure | strategy | | storage | access | Value collection |
+------------+---------------+----------+------------+------------+------------------+
| 2 arrays | Binary search | Sorted | Yes | Key, Index | Yes |
| BST | Binary search | Sorted | No | Key | Yes |
+------------+---------------+----------+------------+------------+------------------+
およそ言い換え、あなたは生のパフォーマンスを必要とする場合SortedDictionary
より良い選択である可能性があります。必要なメモリオーバーヘッドが少なく、インデックス検索がSortedList
適している場合。どちらを使用するかについては、この質問を参照してください。
BDictionary
より通常遅くなりSortedDictionary
、非常に大きなサイズを除いて、それはより速くよりSortedList
700の項目やそこらであるかどうか。ツリーのリーフで配列を使用しているため、メモリ使用量はをわずかに上回るSortedList
(を大幅に下回るSortedDictionary
)必要があります。
について少し混乱があるように見えるので、これを確認するためにReflectorを開いてみましたSortedList
。これは、実際にはバイナリ検索ツリーではなく、キーと値のペアの(キーによって)ソートされた配列です。ありTKey[] keys
、キーと値のペアと同期してソート、バイナリ検索に使用されている変数が。
これが私の主張をバックアップするためのいくつかのソース(.NET 4.5をターゲットにしています)です。
プライベートメンバー
// Fields
private const int _defaultCapacity = 4;
private int _size;
[NonSerialized]
private object _syncRoot;
private IComparer<TKey> comparer;
private static TKey[] emptyKeys;
private static TValue[] emptyValues;
private KeyList<TKey, TValue> keyList;
private TKey[] keys;
private const int MaxArrayLength = 0x7fefffff;
private ValueList<TKey, TValue> valueList;
private TValue[] values;
private int version;
SortedList.ctor(IDictionary、IComparer)
public SortedList(IDictionary<TKey, TValue> dictionary, IComparer<TKey> comparer) : this((dictionary != null) ? dictionary.Count : 0, comparer)
{
if (dictionary == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.dictionary);
}
dictionary.Keys.CopyTo(this.keys, 0);
dictionary.Values.CopyTo(this.values, 0);
Array.Sort<TKey, TValue>(this.keys, this.values, comparer);
this._size = dictionary.Count;
}
SortedList.Add(TKey、TValue):void
public void Add(TKey key, TValue value)
{
if (key == null)
{
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.key);
}
int num = Array.BinarySearch<TKey>(this.keys, 0, this._size, key, this.comparer);
if (num >= 0)
{
ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate);
}
this.Insert(~num, key, value);
}
SortedList.RemoveAt(int):void
public void RemoveAt(int index)
{
if ((index < 0) || (index >= this._size))
{
ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument.index, ExceptionResource.ArgumentOutOfRange_Index);
}
this._size--;
if (index < this._size)
{
Array.Copy(this.keys, index + 1, this.keys, index, this._size - index);
Array.Copy(this.values, index + 1, this.values, index, this._size - index);
}
this.keys[this._size] = default(TKey);
this.values[this._size] = default(TValue);
this.version++;
}
備考セクションから:
SortedList<(Of <(TKey, TValue>)>)
ジェネリッククラスが持つ二分探索木であるO(log n)
検索、n
辞書内の要素の数です。この点で、SortedDictionary<(Of <(TKey, TValue>)>)
ジェネリッククラスに似ています。2つのクラスは同様のオブジェクトモデルを持ち、どちらもO(log n)
検索を行います。2つのクラスが異なるのは、メモリの使用と挿入および削除の速度です。
SortedList<(Of <(TKey, TValue>)>)
はよりも少ないメモリを使用しますSortedDictionary<(Of <(TKey, TValue>)>)
。
SortedDictionary<(Of <(TKey, TValue>)>)
は、O(log n)
とは対照的に、ソートされていないデータの挿入および削除操作が高速O(n)
ですSortedList<(Of <(TKey, TValue>)>)
。リストが並べ替えられたデータから一度に入力される場合
SortedList<(Of <(TKey, TValue>)>)
は、よりも高速ですSortedDictionary<(Of <(TKey, TValue>)>)
。
これは、パフォーマンスの比較方法を視覚的に表したものです。
トピックについてはすでに十分に述べられていますが、簡単にするために、ここに私の見解を示します。
ソートされた辞書は次の場合に使用する必要があります-
反対に、並べ替えられたリストは次の場合に使用する必要があります。
お役に立てれば!!