SortedList와 SortedDictionary의 차이점은 무엇입니까?


261

a SortedList<TKey,TValue>와 a 사이에 실질적인 차이 가 SortedDictionary<TKey,TValue>있습니까? 하나만 사용하고 다른 하나는 사용하지 않는 상황이 있습니까?



13
혼란 스러워요. SortedList에 왜 SortedList<TKey,TValue>하나가 아닌 두 개의 유형 매개 변수 가 SortedList<T>있습니까? 왜 구현하지 IList<T>않습니까?
대령 패닉

3
@ColonelPanic : 기능적으로 SortedList는 선형 컬렉션이 아니라 맵이므로 이름이 당신을 속이게하지 마십시오. 사전과 마찬가지로 키를 전달하면 가치를 얻게됩니다. 사전이 정렬되지 않은 반면 SortedList는 자연 정렬 된 순서로 정렬됩니다.
nawfal

답변:


294

예-성능 특성이 크게 다릅니다. 아마도 그들에게 전화하는 것이 좋습니다 것 SortedList그리고 SortedTree그것은 더 밀접하게 구현을 반영한다.

각기 다른 상황에서 다른 작업의 성능에 대한 자세한 내용은 각 MSDN 문서 ( SortedList, SortedDictionary)를 참조하십시오. 다음은 SortedDictionary문서 에서 요약 한 것입니다 .

SortedDictionary<TKey, TValue>제네릭 클래스는 n은 사전에있는 요소의 수입니다 O (로그 n)이 검색과 이진 검색 트리입니다. 이것에서, 그것은 SortedList<TKey, TValue>일반 클래스 와 유사합니다 . 두 클래스는 비슷한 객체 모델을 가지며 둘 다 O (log n) 검색을 갖습니다. 두 클래스가 다른 곳은 메모리 사용과 삽입 및 제거 속도가 다릅니다.

  • SortedList<TKey, TValue>보다 적은 메모리를 사용합니다 SortedDictionary<TKey, TValue>.

  • SortedDictionary<TKey, TValue>에 대해 O (n)과 반대로 정렬되지 않은 데이터에 대해 O (log n)에 대한 빠른 삽입 및 제거 작업이 SortedList<TKey, TValue>있습니다.

  • 정렬 된 데이터에서 목록이 한 번에 채워지 SortedList<TKey, TValue>면보다 빠릅니다 SortedDictionary<TKey, TValue>.

( SortedList실제로는 오히려 나무를 사용하는 것보다, 정렬 된 배열을 유지합니다. 그것은 여전히 요소를 찾을 수 이진 검색을 사용합니다.)


포인터에 대한 모든 것에 감사드립니다. RTFM에 너무 게으른 것 같아요. 좋은 사람들에게 물어 보는 게 훨씬 쉬워요 ...;) 답을 위해 둘 다 투표했습니다. Jon은 첫 번째 트리거에 대한 답변을 얻습니다. :)
Shaul Behr 2016 년

2
이진 검색 트리라고 생각하지 않기 때문에 SortedList 정의가 수정되어야한다고 생각합니다 ...?
nchaud

1
리플렉터를 사용하여 보았고 바이너리 검색 트리를 사용하지 않는 것으로 나타났습니다.
Daniel Imms 2013

Sorteddictionary는 AVL-tree 또는 Red-Blacktree (모든 작업 비용 O (logn)입니다. SortedList는 이진 검색 (최악의 경우 o (n) 시간이
소요됨

105

도움이된다면 표 형식보기가 있습니다 ...

A로부터 성능 관점 :

+------------------+---------+----------+--------+----------+----------+---------+
| 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<Key,Value>을 원하면 LoycCore 대신을 고려하십시오 SortedDictionary.
Qwertie

1
예, 이 기사 의 하단 부분을보십시오 . 그것은 밝혀 BDictionary보다 일반적으로 느린 SortedDictionary매우 큰 크기를 제외하고,하지만보다 빠른 SortedList이상 700 항목 정도가있는 경우. 트리의 잎에 배열을 사용하기 때문에 메모리 사용량은 SortedList(보다 훨씬 낮음)보다 약간 높아야 SortedDictionary합니다.
Qwertie

22

에 대해 약간의 혼동이있는 것처럼 나는 이것을 확인하기 위해 열린 반사판을 깨뜨렸다 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 (Iictionary, 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++;
}

13

SortedList에 대한 MSDN 페이지를 확인하십시오 .

비고 섹션에서 :

SortedList<(Of <(TKey, TValue>)>)일반적인 클래스와 이진 검색 트리입니다 O(log n)검색, n사전의 요소 수입니다. 이것에서, 그것은 SortedDictionary<(Of <(TKey, TValue>)>)일반 클래스 와 유사합니다 . 두 클래스는 비슷한 객체 모델을 가지고 있으며 둘 다 O(log n)검색합니다. 두 클래스가 다른 곳은 메모리 사용과 삽입 및 제거 속도가 다릅니다.

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


9
인용 텍스트가 잘못되었습니다 (MSDN에서 업데이트 됨). SortedList는 "이진 검색 트리"가 아니며 "키 / 값 쌍의 배열"입니다.
Eldritch Conundrum

12

이것은 성과가 서로 비교되는 방식을 시각적으로 나타낸 것입니다.


그 정보를 어디서 얻었습니까? 이 계획에서 우리는 Dictinary가 어떤 식 으로든 더 낫다는 것을 알 수 있으므로 다른 사람들이 존재할 이유가 없습니다.
alex kostin

9

이미 주제에 대해 충분히 언급되어 있지만 간단하게 유지하려면 여기를 참조하십시오.

정렬 된 사전 은 다음과 같은 경우에 사용해야합니다.

  • 더 많은 삽입 및 삭제 작업이 필요합니다.
  • 순서가없는 데이터
  • 키 액세스는 충분하며 인덱스 액세스는 필요하지 않습니다.
  • 메모리는 병목 현상이 아닙니다.

반면에 정렬 된 목록

  • 더 많은 조회와 더 적은 삽입 및 삭제 작업이 필요합니다.
  • 데이터는 이미 정렬되어 있습니다 (모두는 아니지만 대부분).
  • 인덱스 액세스가 필요합니다.
  • 메모리는 오버 헤드입니다.

도움이 되었기를 바랍니다!!


1

인덱스 액세스 (여기에서 언급)는 실제 차이점입니다. 후임자 또는 전임자에 액세스해야하는 경우 SortedList가 필요합니다. SortedDictionary는 그렇게 할 수 없으므로 정렬을 사용하는 방법 (첫 번째 / foreach)에 상당히 제한적입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.