Почему массив C#.Ищет так быстро?

я реализовал очень просто реализация binarySearch в C# для поиска целых чисел в целочисленном массиве:

Бинарный Поиск

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() is более чем в два раза быстрее как моя функция, каждый раз.

MSDN on массив.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             |
+------------+--------------+--------------------+

1 ответов


ваш код быстрее при запуске вне Visual Studio:

ваш против массива:

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

код массива может быть уже оптимизирован в рамках, но также делает намного больше проверки, чем ваша версия (например, ваша версия может переполниться, если arr.Length больше int.MaxValue / 2) и, как уже было сказано, предназначен для широкого спектра типов, а не только int[].

таким образом, в основном, это медленнее, только когда вы отлаживаете свой код, потому что Код массива всегда выполняется в релиз и с меньшим контролем за кулисами.