List.BinarySearch vs Dictionary.TryGetValue - 更快

时间:2008-12-11 11:47:57

标签: c#

对于500个元素来说会更快。

或者检索元素的数据结构/集合的速度有多快?

        List<MyObj> myObjs = new List<MyObj>();
        int i = myObjs.BinarySearch(myObjsToFind);
        MyObj obj = myObjs[i];

或者

        Dictionary<MyObj, MyObj> myObjss = new Dictionary<MyObj, MyObj>();
        MyObj value;
        myObjss.TryGetValue(myObjsToFind, out value);

5 个答案:

答案 0 :(得分:9)

我假设在您的真实代码中,您实际上填充 myObjs - 并对其进行排序。

你刚试过吗?这取决于几个因素:

  • 您是否需要出于其他原因对列表进行排序?
  • MyObj.CompareTo(MyObj)的速度有多快?
  • MyObj.GetHashCode()的速度有多快?
  • MyObj.Equals()的速度有多快?
  • 你有多大可能发生哈希冲突?
  • 它真的对你产生了重大影响吗?

在二进制搜索案例中,对单个调用GetHashCode和在字典情况下调用Equals(取决于散列冲突)的一些调用,需要进行大约8或9次比较。然后是两种情况下都涉及的内在计算(访问数组等)。

这真的是你的瓶颈吗?

我希望Dictionary在500个元素上快一点,但 very 要快得多。随着收集的增长,差异将明显增加。

答案 1 :(得分:1)

信。

二进制搜索在O(log n)运行,而哈希表为O(1)。

答案 2 :(得分:1)

一些评论者使用的大'O'符号是一个很好的使用指南。但实际上,在特定情况下确定哪种方式更快的唯一方法是在更改之前和之后计算您自己的代码(如Jon所示)。

答案 3 :(得分:0)

BinarySearch要求列表已经排序。 [编辑:忘了字典是哈希表。所以查找是O(1)]。两者也不是一样的。第一个实际上只是检查它是否存在于列表中以及它在哪里。如果您只想检查词典中的存在,请使用contains方法。

答案 4 :(得分:0)

已经用大约 50 万个项目的内存集合进行了一些真实世界的测试。 二分搜索在各方面都胜出。 字典会减慢您拥有的更多哈希冲突。二分搜索在技术上会变慢,但没有字典算法那么快。

二分查找的妙处在于,如果没有找到,它会准确地告诉您将项目插入到列表中的哪个位置......所以制作排序列表也非常快。 (没那么快)

与使用二分搜索排序的列表相比,大的字典也消耗大量内存。根据我的测试,排序列表消耗了大约 27% 的内存字典 id。 (所以一个字典声称内存是 3.7 倍)

对于较小的列表字典就可以了——一旦你变大了,它可能不是最好的选择。