Loop implementação de List.Contains () aparece mais rápido que o interno. É isso? Se sim, porque?

(Esta questão surge de uma discussão que começou aqui)

Eu estava comparando os horários para procurar umtrue valor numList<bool> usandoList.Contains() com aqueles para um loop enrolado à mão.

Estou vendo resultados diferentes daqueles reportados por outras pessoas. Eu tentei em vários sistemas, eo loop parece mais rápido entre 2 e 3,5 vezes em todos os sistemas que eu tentei. Esses sistemas variam de laptops de 5 anos que executam o XP com o .Net 4 para PCs recentes que executam o Windows 8 e o .Net 4.5.

Outras pessoas estão relatando resultados diferentes, ou seja, queList.Contains() tem aproximadamente a mesma velocidade ou um pouco mais rápido que o loop.

Aqui está meu código de teste.

using System;
using System.Collections.Generic;
using System.Diagnostics;

namespace ConsoleApplication1
{
    internal class Program
    {
        private static void Main()
        {
            int size = 10000000;
            int count = 10;
            List<bool> data = new List<bool>(size);

            for (int i = 0; i < size; ++i)
                data.Add(false);

            var sw = new Stopwatch();

            for (int trial = 0; trial < 5; ++trial)
            {
                sw.Restart();

                for (int i = 0; i < count; ++i)
                    TestViaLoop(data);

                sw.Stop();
                Console.WriteLine(sw.ElapsedMilliseconds + " TestViaLoop()");
                sw.Restart();

                for (int i = 0; i < count; ++i)
                    TestViaListContains(data);

                sw.Stop();
                Console.WriteLine(sw.ElapsedMilliseconds + " TestViaListContains()");
                Console.WriteLine();
            }
        }

        static bool TestViaLoop(List<bool> data)
        {
            for (int i = 0; i < data.Count; ++i)
                if (data[i])
                    return true;

            return false;
        }

        static bool TestViaListContains(List<bool> data)
        {
            return data.Contains(true);
        }
    }
}

Para testar esse código, você deve compilá-lo como uma compilação RELEASE x86 e executá-lolado de fora o depurador.

Aqui estão os meus resultados do meu PC com Windows 8 x64 usando o framework .Net 4.5 (embora eu tenha resultados semelhantes com o .net 4):

Times are in milliseconds

126 TestViaLoop()
441 TestViaListContains()

122 TestViaLoop()
428 TestViaListContains()

131 TestViaLoop()
431 TestViaListContains()

138 TestViaLoop()
426 TestViaListContains()

122 TestViaLoop()
439 TestViaListContains()

Como você pode ver, o loop leva em torno de 1/3 do tempo no meu sistema.

Agora, se usarmosResharper olhar para a implementação deList.Contains() Se parece com isso:

bool Contains(T item)
{
    if (item == null)
    {
        for (int j = 0x0; j < this._size; j++)
        {
            if (this._items[j] == null)
            {
                return true;
            }
        }
        return false;
    }
    EqualityComparer<T> comparer = EqualityComparer<T>.Default;
    for (int i = 0x0; i < this._size; i++)
    {
        if (comparer.Equals(this._items[i], item))
        {
            return true;
        }
    }
    return false;
}

Embora esteja usandoComparer.Equals() (o que deve torná-lo mais lento que o loop) ele também está usando o_items[] array diretamente, o que evita a verificação do intervalo do índice que será usado para a implementação do meu loop.

Eu tenho três perguntas:

Alguém mais pode replicar os resultados que estou vendo? (Lembre-se de executar uma compilação de release fora do depurador).Se assim for, alguém pode explicar como o meu loop pode ser muito mais rápido do queList.Contains()?Se não, alguém pode explicar porque eu estou vendo meu loop para ser mais rápido?

Isso não é apenas de interesse acadêmico para mim, já que escrevo códigos que funcionam com grandes quantidades de dados numéricos e que precisam ser o mais rápido possível, e esse é o tipo de coisa que eu preciso saber. (Nota: Sim, faço o perfil das coisas e apenas tento otimizar as coisas que precisam ser otimizadas ... Eu sei sobre os problemas de otimização prematura.)

[EDITAR]

Ocorre-me que isso poderia estar relacionado ao processador. Todos os sistemas que experimentei possuem processadores Intel, embora com modelos muito diferentes, desde o Quad Core a 3.8GHz até um Pentium M single core a 1.6GHz ...

Para aqueles que vêem o loop rodando mais devagar, você está executando processadores Intel?

questionAnswers(2)

yourAnswerToTheQuestion