为什么是c#数组.BinarySearch这么快

本文关键字:BinarySearch 数组 为什么 | 更新日期: 2023-09-27 18:01:18

我已经在c#中实现了一个非常简单的 binarySearch实现,用于在整数数组中查找整数:

<标题>二叉搜索
static int binarySearch(int[] arr, int i)
{
    int low = 0, high = arr.Length - 1, mid;
    while (low <= high)
    {
        mid = (low + high) / 2;
        if (i < arr[mid])
            high = mid - 1;
        else if (i > arr[mid])
            low = mid + 1;
        else
            return mid;
    }
    return -1;
}

当将其与c#的原生Array.BinarySearch()进行比较时,我可以看到Array.BinarySearch()速度是我的函数的两倍以上。

MSDN on Array。BinarySearch:

使用由数组的每个元素和指定对象实现的IComparable泛型接口,在整个一维排序数组中搜索特定元素。

是什么让这个方法这么快?

测试代码
using System;
using System.Diagnostics;
class Program
{
    static void Main()
    {
        Random rnd = new Random();
        Stopwatch sw = new Stopwatch();
        const int ELEMENTS = 10000000;
        int temp;
        int[] arr = new int[ELEMENTS];
        for (int i = 0; i < ELEMENTS; i++)
            arr[i] = rnd.Next(int.MinValue,int.MaxValue);
        Array.Sort(arr);
        // Custom binarySearch
        sw.Restart();
        for (int i = 0; i < ELEMENTS; i++)
            temp = binarySearch(arr, i);
        sw.Stop();
        Console.WriteLine($"Elapsed time for custom binarySearch: {sw.ElapsedMilliseconds}ms");
        // C# Array.BinarySearch
        sw.Restart();
        for (int i = 0; i < ELEMENTS; i++)
            temp = Array.BinarySearch(arr,i);
        sw.Stop();
        Console.WriteLine($"Elapsed time for C# BinarySearch: {sw.ElapsedMilliseconds}ms");
    }
    static int binarySearch(int[] arr, int i)
    {
        int low = 0, high = arr.Length - 1, mid;
        while (low <= high)
        {
            mid = (low+high) / 2;
            if (i < arr[mid])
                high = mid - 1;
            else if (i > arr[mid])
                low = mid + 1;
            else
                return mid;
        }
        return -1;
    }
}
测试结果

+------------+--------------+--------------------+
| Attempt No | binarySearch | Array.BinarySearch |
+------------+--------------+--------------------+
|          1 | 2700ms       | 1099ms             |
|          2 | 2696ms       | 1083ms             |
|          3 | 2675ms       | 1077ms             |
|          4 | 2690ms       | 1093ms             |
|          5 | 2700ms       | 1086ms             |
+------------+--------------+--------------------+

为什么是c#数组.BinarySearch这么快

您的代码在Visual Studio外运行时更快:

你的vs数组的:

From VS - Debug mode: 3248 vs 1113
From VS - Release mode: 2932 vs 1100
Running exe - Debug mode: 3152 vs 1104
Running exe - Release mode: 559 vs 1104

Array的代码可能已经在框架中进行了优化,但也比你的版本做了更多的检查(例如,如果arr.Length大于int.MaxValue / 2,你的版本可能会溢出),并且,正如已经说过的,是为广泛的类型而设计的,而不仅仅是int[]

所以,基本上,只有在调试代码时才会变慢,因为Array的代码总是在release中运行,并且在幕后控制较少。