In un   int?[]    che si è procurato di avere valori originali, volevo trovare l'indice di null, che sarà solo un indice singolo. 
 Ho eseguito il drill su   Array.IndexOf(T[] array, T value)    .NET e, dopo tutti i contratti e i controlli dell'indice, si riduce a questo metodo: 
internal virtual int IndexOf(T[] array, T value, int startIndex, int count){
    int endIndex = startIndex + count;
    for (int i = startIndex; i < endIndex; i++)
        if (Equals(array[i], value)) return i;
    return -1;
}
 Ho tre diverse istanze che tentano un ciclo di base con   array[i] == null   ,   Equals(array[i], null)    e usando   Array.IndexOf(null)   . Mi rendo conto che le zecche e il tempo di cronometro sono relativi a ciò che accade sulla macchina in quel momento e alla macchina in generale. Ma questo è il codice e i benchmark: 
class Program
{
    static void Main(string[] args)
    {
        int?[] jankedArray;
        int missingElement = GenRandomizedArrayWithExtraEmptyElement(10000, out jankedArray);
        var sw = new Stopwatch();
        List<long> DotNetTicks = new List<long>();
        List<long> LikeDotNetTicks = new List<long>();
        List<long> BasicLoopTicks = new List<long>();
        IArrayAnalyzer arrayAnalyzer;
        for (var i = 0; i < 100000; i++)
        {
            arrayAnalyzer = new AnalyzerLikeDotNet();
            sw.Restart(); arrayAnalyzer.GetMissingElement(jankedArray); sw.Stop();
            LikeDotNetTicks.Add(sw.ElapsedTicks);
            arrayAnalyzer = new AnalyzerBasic();
            sw.Restart(); arrayAnalyzer.GetMissingElement(jankedArray); sw.Stop();
            BasicLoopTicks.Add(sw.ElapsedTicks);
            arrayAnalyzer = new AnalyzerUsingDotNet();
            sw.Restart(); arrayAnalyzer.GetMissingElement(jankedArray); sw.Stop();
            DotNetTicks.Add(sw.ElapsedTicks);
        }
        Console.WriteLine("LikeDotNet / DotNet = " + LikeDotNetTicks.Average() / DotNetTicks.Average());
        Console.WriteLine("Basic / DotNet = " + BasicLoopTicks.Average() / DotNetTicks.Average());
        Console.WriteLine("");
        Console.WriteLine("Press the Any key to continue");
        Console.ReadKey();
    }
    public static int GenRandomizedArrayWithExtraEmptyElement(int valueCount, out int?[] incompleteArray)
    {
        incompleteArray = new int?[valueCount + 1];
        Random random = new Random();
        int randomMissingIndex = random.Next(0, valueCount);
        var valueArray = new List<int>();
        for (var i = 1; i <= valueCount; i++) valueArray.Add(i);
        var arrayElementAt = 0;
        while (valueArray.Count > 0)
        {
            if (arrayElementAt != randomMissingIndex)
            {
                var randomElement = random.Next(0, valueArray.Count);
                var valueAtRandom = valueArray.ElementAt(randomElement);
                valueArray.RemoveAt(randomElement);
                incompleteArray[arrayElementAt] = valueAtRandom;
            }
            arrayElementAt++;
        }
        return randomMissingIndex;
    }
}
public interface IArrayAnalyzer
{
    int GetMissingElement(int?[] incompleteArray);
}
public class AnalyzerUsingDotNet : IArrayAnalyzer
{
    public int GetMissingElement(int?[] incompleteArray)
    {
        return Array.IndexOf(incompleteArray, null);
    }
}
public class AnalyzerLikeDotNet : IArrayAnalyzer
{
    public int GetMissingElement(int?[] array)
    {
        for (int i = 0; i < array.Length; i++)
            if (Equals(array[i], null)) return i;
        return -1;
    }
}
public class AnalyzerBasic : IArrayAnalyzer
{
    public int GetMissingElement(int?[] array)
    {
        for (int i = 0; i < array.Length; i++)
            if (array[i] == null) return i;
        return -1;
    }
}
- Output:
 - LikeDotNet / DotNet = 81.3577324867023
 - Base / DotNet = 3.29459064916075
 
Cosa mi manca tra AnalyzerLikeDotNet e AnalyzerUsingDotNet che rende così diverso il tempo di esecuzione?