SortedList ve SortedDictionary arasındaki fark nedir?


261

A arasında gerçek bir pratik fark var mı SortedList<TKey,TValue> ve aSortedDictionary<TKey,TValue> ? Birini diğerini değil, özellikle kullanacağınız durumlar var mı?



13
Kafam karıştı. SortedList'in neden bir SortedList<TKey,TValue>yerine iki tür parametresi var SortedList<T>? Neden uygulanmıyor IList<T>?
Albay Panik

3
@ColonelPanic çünkü işlevsel olarak SortedList doğrusal bir koleksiyon değil bir haritadır. Adın seni kandırmasına izin verme. Tıpkı bir sözlük gibi, bir anahtar veriyorsunuz, bir değer geri alıyorsunuz. Sözlük sıralanmamışken, SortedList doğal sıralama düzeninde sıralanır.
nawfal

Yanıtlar:


294

Evet - performans özellikleri önemli ölçüde farklılık gösterir. Muhtemelen onları aramak daha iyi olur SortedListve SortedTreebu da uygulamayı daha yakından yansıtır.

Farklı durumlardaki farklı işlemlerin performansıyla ilgili ayrıntılar için her biri için MSDN belgelerine bakın ( SortedList, SortedDictionary). İşte güzel bir özet ( SortedDictionarydokümanlardan):

SortedDictionary<TKey, TValue>Jenerik sınıf n sözlükte eleman sayısıdır O (log n) alma, bir ikili arama ağacı. SortedList<TKey, TValue>Bunda jenerik sınıfa benzer . İki sınıf benzer nesne modellerine sahiptir ve her ikisinde de O (log n) alımı vardır. İki sınıfın farklı olduğu yerler bellek kullanımı ve takma ve çıkarma hızıdır:

  • SortedList<TKey, TValue>daha az bellek kullanır SortedDictionary<TKey, TValue>.

  • SortedDictionary<TKey, TValue>sıralanmamış veriler için daha hızlı ekleme ve çıkarma işlemleri vardır, O (log n), O (n) yerine SortedList<TKey, TValue>.

  • Liste sıralı verilerden bir defada doldurulursa SortedList<TKey, TValue>, daha hızlıdır SortedDictionary<TKey, TValue>.

( SortedListaslında bir ağaç kullanmak yerine sıralanmış bir diziyi korur. Öğeleri bulmak için yine de ikili arama kullanır.)


İşaretçiler için herkese çok teşekkürler. Sanırım RTFM'ye çok tembelim ... SO'daki güzel insanlara sormak çok daha kolay ...;) İkinize de cevaplar için oy verdim; Jon ilk tetikte olduğu için cevap kredisi alır. :)
Behr

2
Bence bir ikili arama ağacı olduğuna inanmıyorum SortedList tanımı düzeltilmelidir ...?
nchaud

1
Reflektör kullanarak baktım ve ikili bir arama ağacı kullanmadığını gördüm.
Daniel Imms

Bence Sorteddictionary bir AVL ağacı veya Red-Blacktree (tüm operasyon maliyeti O (logn). Ve SortedList bir ikili arama (en kötü durumda o (n) zaman maliyeti) l
Ghoster

105

İşte yardımcı oluyorsa tablo görünümü ...

Bir itibaren performans perspektifinden:

+------------------+---------+----------+--------+----------+----------+---------+
| 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).

Bir itibaren uygulanması bakış açısı:

+------------+---------------+----------+------------+------------+------------------+
| 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              |
+------------+---------------+----------+------------+------------+------------------+

To kabaca ham performans gerektiriyorsa başka kelimelerle, SortedDictionarydaha iyi bir seçim olabilir. Daha az bellek ek yükü ve endeksli alım gerekiyorsa SortedListdaha iyi uyuyor.Hangisinin ne zaman kullanılacağı hakkında daha fazla bilgi için bu soruya bakın.

Burada , burada , burada , burada ve burada daha fazlasını okuyabilirsiniz .


İyi performans ve nispeten düşük bellek kullanımı ve dizine BDictionary<Key,Value>alınmış erişim istiyorsanız, bunun yerine LoycCore'u dikkate alınSortedDictionary .
Qwertie

1
Evet, bu makalenin alt kısmına bakın . BDictionaryGenellikle SortedDictionaryçok büyük boyutlar dışındakinden daha yavaş ortaya çıkıyor , ancak SortedList700'den fazla öğe olduğundan daha hızlı . Bellek kullanımı sadece biraz daha yüksek olmalıdır SortedList(çok daha düşük SortedDictionarynedeni ağacın yapraklarında diziler kullanımına,).
Qwertie

22

Bu konuda bir göz atmak için açık Reflektörü kırdım, çünkü biraz karışıklık var gibi görünüyor SortedList. Aslında bir ikili arama ağacı değildir , anahtar / değer çiftlerinin sıralı (anahtar ile) dizisidir . Ayrıca, TKey[] keysanahtar / değer çiftleriyle senkronize olarak sıralanan ve ikili arama için kullanılan bir değişken de vardır .

İşte iddialarımı yedeklemek için bazı kaynak (.NET 4.5 hedefleme).

Özel üyeler

// 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): geçersiz

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): geçersiz

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++;
}

13

SortedList için MSDN sayfasına göz atın :

Açıklamalar bölümünden:

SortedList<(Of <(TKey, TValue>)>)Jenerik sınıf bir ikili arama ağacı O(log n)alımı, nsözlükte elemanların sayısıdır. SortedDictionary<(Of <(TKey, TValue>)>)Bunda jenerik sınıfa benzer . İki sınıf benzer nesne modellerine sahiptir ve her ikisi de O(log n)geri çağırma özelliğine sahiptir. İki sınıfın farklı olduğu yerler bellek kullanımı ve takma ve çıkarma hızıdır:

  • SortedList<(Of <(TKey, TValue>)>)daha az bellek kullanır SortedDictionary<(Of <(TKey, TValue>)>).
  • SortedDictionary<(Of <(TKey, TValue>)>)Daha hızlı yerleştirilmesini ve sıralanmamış veriler için kaldırma işlemleri vardır O(log n)karşı O(n)için SortedList<(Of <(TKey, TValue>)>).

  • Liste sıralı verilerden bir defada doldurulursa SortedList<(Of <(TKey, TValue>)>), daha hızlıdır SortedDictionary<(Of <(TKey, TValue>)>).


9
Alıntılanan metin yanlış (ve MSDN'de güncellendi): SortedList bir "ikili arama ağacı" değil, bir "anahtar / değer çifti dizisidir".
Eldritch Conundrum

12

Bu, performansların birbirleriyle nasıl karşılaştırıldığının görsel temsilidir.


Bu bilgiyi nereden aldın? Bu şemadan, Diktatörün herhangi bir şekilde daha iyi olduğunu görebiliriz, bu yüzden başkalarının var olması için hiçbir neden yoktur.
alex kostin

9

Yeterince konuyla ilgili zaten söyleniyor, ancak basit tutmak için benim almam.

Sıralı sözlük şu durumlarda kullanılmalıdır:

  • Daha fazla ekleme ve silme işlemi gerekir.
  • Veriler sıralanmamış.
  • Anahtar erişimi yeterlidir ve dizin erişimi gerekli değildir.
  • Bellek bir darboğaz değildir.

Diğer tarafta, Sıralı Liste aşağıdaki durumlarda kullanılmalıdır.

  • Daha fazla arama ve daha az kesici uç ve silme işlemi gerekir.
  • Veriler zaten sıralanmıştır (hepsi değilse de, çoğu).
  • Dizin erişimi gerekiyor.
  • Bellek bir yüktür.

Bu yardımcı olur umarım!!


1

İndeks erişimi (burada belirtilmiştir) pratik farktır. Halef veya selefine erişmeniz gerekiyorsa SortedList'e ihtiyacınız var. SortedDictionary bunu yapamaz, bu nedenle sıralama (ilk / foreach) nasıl kullanabileceğiniz ile oldukça sınırlıdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.