我们有一个
SortedList<Resource, Resource> resources =
new SortedList<Resource, Resource>(new ResourceIdle());
我们在模拟中使用的。这个资源列表以这种方式初始化,因为我们希望在任何时间点传递不同的比较器。我们遇到的第一个问题是SortedList<>
需要在比较器中进行额外的比较,以便我们可以添加具有相同属性的Resource
的不同实例。例如,如果Comparer看起来像:
public int Compare(Resource x, Resource y)
{
int priority1 = x.Priority;
int priority2 = y.Priority;
if (priority1 > priority2) {
return -1;
} else if (priority1 < priority2) {
return 1;
} else {
return (x.Id.CompareTo(y.Id));
}
}
然后我们必须在优先级相同时进行额外的比较,否则我们会返回具有相同键的条目的异常。所以我的问题是,还有另一种方法可以达到这个目的吗?而作为次要问题,有什么比SortedList<>
更快的订购大量对象?
答案 0 :(得分:12)
好吧,SortedDictionary<,>
具有不同的性能特征 - 这取决于您正在使用它做什么。 MSDN比较两者有很多细节:
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>
快。
答案 1 :(得分:2)
要求列表始终随时排序吗?如果没有,只按需排序肯定会更快。另一个想法是通过“OrderPriority”完成排序,它是Priority和ID字段的组合,因此只需要进行一次比较:
int OrderPriority { get { return Priority * MAX_ID + ID; } }
这假设ID不会太大......
答案 2 :(得分:2)
您可以稍微缩短比较:
public int Compare(Resource x, Resource y)
{
int priority1 = x.Priority;
int priority2 = y.Priority;
if (priority1 != priority2)
return priority2 - priority1;
return (x.Id.CompareTo(y.Id));
}
答案 3 :(得分:2)
如果您不关心区分具有相同优先级的对象,为什么不使用桶的SortedList(可能实现为队列),同一桶中所有具有相同优先级的项目?
答案 4 :(得分:0)
当您从字典创建SortedList
时,它会将键和值复制到数组中,然后使用Array.Sort
方法对它们进行排序,这样几乎和您一样快,除非您对该集合有一些特殊的了解,否则可以帮助您选择更适合该特殊情况的不同算法。
但是,看起来您正在创建一个具有相同键和值的字典,以便能够使用SortedList
。如果是这种情况,您应该将项目放在数组或列表中并对它们进行排序。 Array.Sort
和List<T>.Sort
方法也可以使用自定义比较器。
您与二级比较的比较可以简化为:
public int Compare(Resource x, Resource y) {
int result = x.Priority.CompareTo(y.Priority);
if (result == 0) {
result = x.Id.CompareTo(y.Id);
}
return result;
}