C#比SortedList更快排序<>

时间:2010-09-28 19:07:49

标签: c# sorting sortedlist

我们有一个

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<>更快的订购大量对象?

5 个答案:

答案 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.SortList<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;
}