La implementación en bucle de List.Contains () aparece más rápido que la incorporada. ¿Lo es? Si es así, ¿por qué?

(Esta pregunta surge de una discusión que comenzó aquí.)

Estaba comparando los horarios para buscar untrue valor en unList<bool> utilizandoList.Contains() Con los de un bucle enrollado a mano.

Estoy viendo resultados diferentes de los reportados por otras personas. Lo he probado en varios sistemas, y el bucle parece más rápido entre 2 y 3.5 veces en todos los sistemas en los que lo he probado. Estos sistemas van desde computadoras portátiles con 5 años de antigüedad que ejecutan XP con .Net 4 a PC recientes que ejecutan Windows 8 y .Net 4.5.

Otras personas están reportando diferentes resultados, a saber, queList.Contains() es aproximadamente la misma velocidad que, o ligeramente más rápida que, el bucle.

Aquí está mi código de prueba.

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 probar este código, debe compilarlo como una compilación RELEASE x86 y ejecutarlo desdefuera de el depurador

Aquí están mis resultados de mi PC con Windows 8 x64 usando el marco .Net 4.5 (aunque obtengo resultados similares con .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 puede ver, el bucle toma alrededor de 1/3 del tiempo en mi sistema.

Ahora si usamosResharper Para ver la implementación deList.Contains() se parece a esto:

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

Aunque está usandoComparer.Equals() (lo que debería hacer que sea más lento que el bucle) también está utilizando el privado_items[] directamente, lo que evita la verificación de rango de índice que se utilizará para la implementación de mi bucle.

Tengo tres preguntas:

¿Puede alguien más replicar los resultados que estoy viendo? (Recuerde ejecutar una versión de compilación fuera del depurador).Si es así, ¿alguien puede explicar cómo mi bucle puede ser mucho más rápido queList.Contains()?Si no, ¿puede alguien explicar por qué veo que mi bucle es más rápido?

Esto no solo es de interés académico para mí, ya que escribo un código que funciona con grandes cantidades de datos numéricos y que debe ser lo más rápido posible, y este es el tipo de cosas que debo conocer. (Nota: Sí, hago un perfil de las cosas y solo trato de optimizar las cosas que deben optimizarse ... Conozco los problemas de la optimización prematura).

[EDITAR]

Se me ocurre que esto podría estar relacionado con el procesador. Todos los sistemas en los que lo he probado tienen procesadores Intel, aunque hay modelos muy diferentes que van desde Quad Core a 3.8GHz a un Pentium M single core a 1.6 GHz ...

Para aquellos de ustedes que ven que el ciclo se ejecuta más lento, ¿están ejecutando procesadores Intel?

Respuestas a la pregunta(2)

Su respuesta a la pregunta