SortedList与SortedDictionary vs. Sort()

时间:2010-01-10 11:52:14

标签: .net performance sorting sortedlist sorteddictionary

这是this one等问题的延续。

是否有任何调整性能的指南?我并不是指大O的收益,只是节省一些线性时间。

例如,预排序可以节省多少SortedListSortedDictionary

假设我有一个有3个属性要排序的人类,其中一个是年龄。我应该先按年龄换取物品吗?

我应该首先对一个属性进行排序,然后使用结果列表/字典对两个属性进行排序,依此类推?

任何其他优化的想法?

1 个答案:

答案 0 :(得分:57)

嗯,这在SortedList上轻松获胜。插入项目需要二进制搜索(O(log(n))来查找插入点,然后使用List.Insert(O(n))来插入项目.Insert()占主导地位,填充列表需要O(n ^ 2)。如果输入项已经排序,那么Insert会折叠到O(1)但不会影响搜索。填充现在是O(nlog(n))。你不用担心哦有多大,首先排序总是更有效率。假设您能够承受双倍的存储需求。

SortedDictionary不同,它使用红黑树。查找插入点需要O(log(n))。之后可能需要重新平衡树,这也需要O(log(n))。因此填充字典需要O(nlog(n))。使用排序输入不会改变查找插入点或重新平衡的工作量,它仍然是O(nlog(n))。现在,哦很重要,插入已排序的输入需要树本身不断重新平衡。如果输入是随机的,你不需要排序输入,效果会更好。

所以使用排序输入填充SortedList并使用未排序的输入填充SortedDictionary是O(nlog(n))。忽略提供排序输入的成本,SortedList的Oh小于SortedDictionary的Oh。由于List分配内存的方式,这是一个实现细节。它只需要执行O(log(n))次,红黑树必须分配O(n)次。非常小哦,顺便说一句。

值得注意的是,没有人比简单地填充List,然后调用Sort()更有利。这也是O(nlog(n))。实际上,如果输入已被意外排序,则可以绕过Sort()调用,这会折叠为O(n)。现在,成本分析需要转移到输入排序所需的工作量。很难绕过Sort(),O(nlog(n))的基本复杂性。它可能不容易看到,您可能会获得按SQL查询排序的输入。它只需要更长的时间才能完成。

使用SortedList或SortedDictonary的目的是在插入后对集合进行排序。如果您只担心填充而不是变异,那么您不应该使用这些集合。