15

I have implemented a very simple binarySearch implementation in C# for finding integers in an integer array:

Binary Search

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;
}

When comparing it to C#'s native Array.BinarySearch() I can see that Array.BinarySearch() is more than twice as fast as my function, every single time.

MSDN on Array.BinarySearch:

Searches an entire one-dimensional sorted array for a specific element, using the IComparable generic interface implemented by each element of the Array and by the specified object.

What makes this approach so fast?

Test code

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;
    }
}

Test results

+------------+--------------+--------------------+
| Attempt No | binarySearch | Array.BinarySearch |
+------------+--------------+--------------------+
|          1 | 2700ms       | 1099ms             |
|          2 | 2696ms       | 1083ms             |
|          3 | 2675ms       | 1077ms             |
|          4 | 2690ms       | 1093ms             |
|          5 | 2700ms       | 1086ms             |
+------------+--------------+--------------------+
11
  • 9
    You can take a look at the source for hints. Commented Aug 8, 2016 at 20:44
  • 4
    Did you run your test in Release outside of VS? Commented Aug 8, 2016 at 20:45
  • 6
    I just did, and on my machine your binarySearch is about 2.5 times faster than the Array one. Commented Aug 8, 2016 at 20:57
  • Probably because they wrote better (i.e., more performant) code than yours. Analyze the code @Blorgbeard linked Commented Aug 8, 2016 at 20:58
  • 2
    @IvanStoev me too, same result. I'm guessing hard-coding the data-type to int makes for much faster comparisons. Commented Aug 8, 2016 at 21:02

1 Answer 1

17

Your code is faster when run outside Visual Studio:

Yours vs Array's:

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's code might be already optimized in the framework but also does a lot more checking than your version (for instance, your version may overflow if arr.Length is greater than int.MaxValue / 2) and, as already said, is designed for a wide range of types, not just int[].

So, basically, it's slower only when you are debugging your code, because Array's code is always run in release and with less control behind the scenes.

Sign up to request clarification or add additional context in comments.

5 Comments

Can you comment the line: Array.Sort(arr) and post your result again.
@M.Hassan binary search requires a sorted array as input. The sort is not being included in the timings.
Very interesting answer and I can reproduce the same results. Marked as accepted
This answer contradicts itself. it says that "it's slower only when [not in release]", but the numbers posted show that in Release Mode, in VS, the performance is about as slow as in Debug Mode: so what accounts for that?
By "debugging" I was referring to either executing a binary in "debug mode" or running the code from within Visual Studio, which can still be considered "debugging" even using "release mode".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.