Answers:
在两个元素中的任何一个元素上进行迭代时,将对元素进行排序。并非如此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)对未排序的数据具有更快的插入和删除操作:O(log n)与SortedList(TKey,TValue)的O(n)相反。
如果从排序数据中一次填充列表,则SortedList(TKey,TValue)比SortedDictionary(TKey,TValue)快。
SortedList
您可以按索引检索(而不是按键检索),而SortedDictionary
不能。
我会提到字典之间的区别。
上图显示了Dictionary<K,V>
在每种情况下它都比Sorted
模拟量相等或更快,但是如果需要元素顺序(例如打印它们),Sorted
则选择一个。
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与字典与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
:如果您填充您的集合中的一个镜头- >去排序列表,但如果你预计你会经常需要.Add
与.Remove
项目- >去SortedDictionary。
sorted
是什么意思:当您执行a For Each MyItem in Collection
而不是按照最初.Add
编辑项目的顺序进行处理时,a sorted
Collection
将按照Key
值(在中定义IComparer
)的顺序对它们进行处理。例如,如果您的键是字符串,则默认情况下将按照键的字母顺序处理您的集合,但是您始终可以定义自定义排序规则。
我可以看到建议的答案集中在性能上。下面提供的文章并未提供有关性能的任何新信息,但它解释了潜在的机制。还要注意,它不关注Collection
问题中提到的三种类型,而是解决了System.Collections.Generic
名称空间的所有类型。
字典可能是最常用的关联容器类。字典是关联查找/插入/删除最快的类,因为它在底下使用哈希表。因为键是散列的,所以键类型应正确地正确实现GetHashCode()和Equals(),或者在构造时应为字典提供外部IEqualityComparer。字典中项目的插入/删除/查找时间是摊销的恒定时间-O(1)-这意味着,不管字典有多大,查找某物所花费的时间都保持相对恒定。这对于高速查找是非常理想的。唯一的缺点是,根据使用哈希表的性质,字典是无序的,因此您无法轻松地依次遍历字典中的项目。
SortedDictionary在用法上类似于Dictionary,但在实现上有很大不同。该SortedDictionary底层使用二叉树通过钥匙来维持秩序中的项目。排序的结果是,用于键的类型必须正确实现IComparable,以便可以正确地对键进行排序。排序后的字典需要一些查找时间,才能维护项目的顺序,因此排序字典中的插入/删除/查找时间是对数-O(log n)。一般而言,使用对数时间,您可以将集合的大小增加一倍,并且只需执行一次额外的比较即可找到该项目。当您想要快速查找但又希望能够通过键来维护集合时,请使用SortedDictionary。
SortedList是通用容器中的另一个已排序的关联容器类。与SortedDictionary一样,SortedList再次使用键对键值对进行排序。但是,与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(log n)的(排序的数组)HashArray(i)
#O(n)(排序数组)KeyArray(i)
#O(1)ItemArray(i)
#O(1)获取物品
For i = 0 to n
,在i
哪里找到HashArray(i) = Key.GetHash
#O(log n)的(排序的数组)ItemArray(i)
依次通过
For i = 0 to n
,返回 ItemArray(i)
分类词典
记忆
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(log n)的KeyArray(i) = PointerToKey
#O(n)ItemArray(i) = PointerToItem
#O(n)去掉
For i = 0 to n
,在i
哪里找到KeyArray(i).GetHash = Key.GetHash
#O(log n)KeyArray(i)
#O(n)ItemArray(i)
#O(n)获取物品
For i = 0 to n
,找到#O(log n)i
在哪里KeyArray(i).GetHash = Key.GetHash
ItemArray(i)
依次通过
For i = 0 to n
,返回 ItemArray(i)
尝试为@Lev提出的每种情况分配性能得分,我使用以下值:
结果是(越高=越好):
Dictionary: 12.0
SortedDictionary: 9.0
SortedList: 6.5
当然,每个用例都会为某些操作赋予更多的权重。