【问题标题】:BinarySearch is so slowBinarySearch 太慢了
【发布时间】:2014-06-07 02:21:00
【问题描述】:

当我在 SortedList 上使用 .net BinarySearch 时,怎么会比我在同一个列表上使用自己制作的二进制搜索方法花费的时间要长得多?

使用 .net 二进制搜索:

int ipos = MyList.Keys.ToList().BinarySearch(unSearchFor);

if (ipos >= 0)
{
    // exact target found at position "ipos"
    return MyList[unSearchFor];
}
else
{
    // Exact key not found: 
    // BinarySearch returns negative when the exact target is not found,
    // which is the bitwise complement of the next index in the list larger than the target.
    ipos = ~ipos;
    try
    {
        return MyList.Values[ipos - 1];
    }
    catch
    {
        return null;
    }
}

我的二分查找方法:

int nStart = 0;
int nEnd = MyList.Count - 1;
int mid = 0;

while (nStart <= nEnd)
{
    mid = nStart + (nEnd - nStart) / 2;
    uint unCurrKey = MyList.Values[mid].Key;

    if (unSearchFor == unCurrKey)
        return MyList.Values[mid];

    if (unSearchFor < unCurrKey)
    {
        nEnd = mid - 1;
    }
    else
    {
        nStart = mid + 1;
    }
}

【问题讨论】:

  • 您如何衡量这些方法?结果如何?
  • 第一个对键集合进行二进制搜索,第二个似乎没有触及集合的键。你确定这两种算法在做同样的事情吗?
  • 可能有例外?这些抛出和捕获的成本很高,并且第二个中的不同算法似乎不会抛出/捕获异常以return null。如果没有您的测试数据集和有关您的基准测试方法的信息,我们实际上只是在猜测。
  • 不能同意异常是昂贵的:如果在一个巨大的循环中抛出捕获,那么是的,否则 - 不是。而且肯定不是性能瓶颈。
  • 避免try-catch的原因不是为了性能。这是因为您使用了一个简单的 if 会做的异常。 不要将异常用作非异常场景控制流机制。这是一种非常糟糕的编程习惯。

标签: c# .net performance binary-search


【解决方案1】:

难道不是因为你在下面的列表中调用 BinarySearch() 时正在执行 .ToList() 吗?

MyList.Keys.ToList().BinarySearch(unSearchFor);

【讨论】:

  • 不知道你为什么得到-1。第一个算法是 O(n),其中正确的二分搜索是 O(log n)。您肯定已经在示例中发现了一个会严重影响性能的算法错误。
  • 我必须 ToList 才能调用 BinarySearch,这种方法时间成本高吗?我以为这只是改变类型..
  • 是的,它有 O(n) 的性能影响。 stackoverflow.com/questions/15516462/…
  • @user3535426 能否请您将此标记为答案
猜你喜欢
  • 2013-03-10
  • 2016-05-31
  • 2011-07-07
  • 2015-08-23
  • 2012-07-05
  • 2016-01-08
  • 2014-03-12
  • 2021-03-26
  • 2011-10-26
相关资源
最近更新 更多