나는 그것을 찾을 수 SortedList<TKey, TValue>
SortedDictionary<TKey, TValue>
와 Dictionary<TKey, TValue>
같은 인터페이스를 구현합니다.
- 우리는을 선택해야하는 경우
SortedList
와SortedDictionary
이상Dictionary
? - 의 차이 무엇입니까
SortedList
및SortedDictionary
응용 프로그램의 측면에서는?
답변:
둘 중 하나의 요소를 반복하면 요소가 정렬됩니다. 그리로 Dictionary<T,V>
.
MSDN 은 SortedList<T,V>
과 (와) 의 차이점을 해결합니다 SortedDictionary<T,V>
.
SortedDictionary (TKey, TValue) 제네릭 클래스는 O (log n) 검색 이 포함 된 이진 검색 트리 입니다. 여기서 n은 사전의 요소 수입니다. 이 점에서 SortedList (TKey, TValue) 제네릭 클래스와 유사합니다. 두 클래스는 유사한 객체 모델을 가지고 있으며 둘 다 O (log n) 검색을 가지고 있습니다. 두 클래스가 다른 점은 메모리 사용과 삽입 및 제거 속도입니다.
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
하나를 선택합니다.
Immutable
이러한 사전 의 버전 중 하나를 선택 하면 Sorted
버전이 정렬되지 않은 버전보다 실제로 약 40 ~ 50 % 더 빠르다는 점에 유의해야합니다 (여전히 O(log(n))
이지만 작업 당 눈에 띄게 빠름). . 그러나 입력이 정렬 된 방식에 따라 타이밍이 다를 수 있습니다. 참조 stackoverflow.com/a/30638592/111575
성능 테스트-SortedList vs. SortedDictionary vs. Dictionary vs. 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
질문에 언급 된 세 가지 유형 에 초점을 맞추지 않고 System.Collections.Generic
네임 스페이스 의 모든 유형을 다룹니다 .
사전은 아마도 가장 많이 사용되는 연관 컨테이너 클래스 일 것입니다. Dictionary는 내부적 으로 해시 테이블을 사용 하기 때문에 연관 조회 / 삽입 / 삭제를위한 가장 빠른 클래스입니다 . 키가 해시되기 때문에 키 유형이 GetHashCode () 및 Equals ()를 올바르게 구현 하거나 생성시 사전에 외부 IEqualityComparer를 제공해야합니다. 사전에있는 항목의 삽입 / 삭제 / 조회 시간은 일정 시간 (O (1))으로 상각됩니다. 즉, 사전이 아무리 커도 무언가를 찾는 데 걸리는 시간은 상대적으로 일정하게 유지됩니다. 이것은 고속 조회에 매우 바람직합니다. 유일한 단점 은 해시 테이블 사용의 특성상 사전이 순서가 지정되지 않았기 때문에사전에있는 항목을 순서대로 쉽게 순회 할 수 없습니다 .
SortedDictionary는 사용법이 Dictionary와 비슷하지만 구현이 매우 다릅니다. SortedDictionary은 키 순서대로 항목을 유지하기 위해 내부적으로 이진 트리를 사용합니다 . 정렬의 결과로 키에 사용되는 형식 은 키가 올바르게 정렬 될 수 있도록 IComparable을 올바르게 구현해야합니다 . 정렬 된 사전은 항목을 순서대로 유지하는 능력을 위해 약간의 조회 시간을 교환하므로 정렬 된 사전의 삽입 / 삭제 / 조회 시간은 로그-O (log n)입니다. 일반적으로 로그 시간을 사용하면 컬렉션 크기를 두 배로 늘릴 수 있으며 항목을 찾기 위해 추가 비교를 한 번만 수행하면됩니다. 빠른 조회를 원하지만 컬렉션을 키별로 순서대로 유지하려면 SortedDictionary를 사용하십시오.
SortedList는 제네릭 컨테이너의 다른 정렬 된 연관 컨테이너 클래스입니다. 다시 한번 SortedList는 SortedDictionary와 마찬가지로 키를 사용하여 키-값 쌍을 정렬합니다 . 그러나 SortedDictionary와 달리 SortedList의 항목은 정렬 된 항목 배열로 저장됩니다.. 즉, 항목을 삭제하거나 추가하면 목록에서 모든 항목을 위나 아래로 이동할 수 있기 때문에 삽입 및 삭제가 선형 (O (n))입니다. 그러나 조회 시간은 O (log n)입니다. SortedList는 이진 검색을 사용하여 키로 목록의 항목을 찾을 수 있기 때문입니다. 그렇다면 왜 이렇게하고 싶습니까? 음, 정답은 SortedList를 미리로드하려는 경우 삽입 속도가 느리지 만 배열 인덱싱이 다음 개체 링크보다 빠르기 때문에 조회가 SortedDictionary보다 약간 빠릅니다. 다시 한 번 빠른 조회를 원하고 키에 따라 컬렉션을 순서대로 유지하고 삽입 및 삭제가 거의없는 상황에서 이것을 사용합니다.
내가 모든 것을 올바르게 얻지 못했다고 확신하므로 피드백은 매우 환영합니다.
n
입니다.사전
기억
KeyArray(n) -> non-sorted array<pointer>
ItemArray(n) -> non-sorted array<pointer>
HashArray(n) -> sorted array<hashvalue>
더하다
HashArray(n) = Key.GetHash
#O (1) 추가KeyArray(n) = PointerToKey
#O (1) 추가ItemArray(n) = PointerToItem
#O (1) 추가없애다
For i = 0 to n
찾을 i
곳 HashArray(i) = Key.GetHash
# O (로그 N) (정렬 된 배열)HashArray(i)
# O (n) (정렬 된 배열)KeyArray(i)
# O (1)ItemArray(i)
# O (1)아이템 받기
For i = 0 to n
찾을 i
곳 HashArray(i) = Key.GetHash
# O (로그 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
#O (1) 추가ItemArray(n) = PointerToItem
#O (1) 추가For i = 0 to n
찾을 i
곳 KeyArray(i-1) < Key < KeyArray(i)
(사용 ICompare
) #의 O (N)를OrderArray(i) = n
# O (n) 추가 (정렬 된 배열)없애다
For i = 0 to n
, i
위치 KeyArray(i).GetHash = Key.GetHash
# O (n)KeyArray(SortArray(i))
# O (n)ItemArray(SortArray(i))
# O (n)OrderArray(i)
# O (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의 (로그 N)를KeyArray(i) = PointerToKey
# O (n) 추가ItemArray(i) = PointerToItem
# O (n) 추가없애다
For i = 0 to n
찾을 i
경우 KeyArray(i).GetHash = Key.GetHash
#의 O (로그 N)KeyArray(i)
# O (n)ItemArray(i)
# O (n)아이템 받기
For i = 0 to n
찾을 i
경우 KeyArray(i).GetHash = Key.GetHash
#의 O (로그 N)ItemArray(i)
루프 스루
For i = 0 to n
, 반환 ItemArray(i)
@Lev가 제시 한 각 사례에 성능 점수 를 할당하려고 시도 하면서 다음 값을 사용했습니다.
결과는 다음과 같습니다 (높을수록 좋음).
Dictionary: 12.0
SortedDictionary: 9.0
SortedList: 6.5
물론 모든 사용 사례는 특정 작업에 더 많은 가중치를 부여합니다.