Die Loop-Implementierung von List.Contains () erscheint schneller als die integrierte. Ist es? Wenn ja warum?

(Diese Frage ergibt sich aus einer Diskussion, die hier begonnen hat)

Ich verglich die Zeiten für die Suche nach einemtrue Wert in aList<bool> mitList.Contains() mit denen für eine handgerollte Schleife.

Ich sehe andere Ergebnisse als von anderen Personen. Ich habe es auf mehreren Systemen ausprobiert, und die Schleife scheint auf allen Systemen, auf denen ich es ausprobiert habe, um das 2- bis 3,5-fache schneller zu sein. Diese Systeme reichen von 5 Jahre alten Laptops mit XP mit .Net 4 bis zu neueren PCs mit Windows 8 und .Net 4.5.

Andere Leute berichten über andere Ergebnisse, nämlich dasList.Contains() entspricht in etwa der Geschwindigkeit der Schleife oder ist etwas schneller als diese.

Hier ist mein Testcode.

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

Um diesen Code zu testen, sollten Sie ihn als x86 RELEASE-Build kompilieren und von dort ausführendraußen der Debugger.

Hier sind meine Ergebnisse von meinem Windows 8 x 64-PC unter Verwendung des .Net 4.5-Frameworks (obwohl ich mit .Net 4 ähnliche Ergebnisse erhalte):

Times are in milliseconds

126 TestViaLoop()
441 TestViaListContains()

122 TestViaLoop()
428 TestViaListContains()

131 TestViaLoop()
431 TestViaListContains()

138 TestViaLoop()
426 TestViaListContains()

122 TestViaLoop()
439 TestViaListContains()

Wie Sie sehen, dauert die Schleife auf meinem System ungefähr 1/3 der Zeit.

Nun, wenn wir verwendenResharper auf die Umsetzung von schauenList.Contains() es sieht aus wie das:

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

Obwohl es verwendet wirdComparer.Equals() (was es langsamer machen sollte als die Schleife), verwendet es auch die private_items[] Direktes Array, wodurch die Überprüfung des Indexbereichs vermieden wird, der für meine Schleifenimplementierung verwendet wird.

Ich habe drei Fragen:

Kann jemand anderes die Ergebnisse wiederholen, die ich sehe? (Denken Sie daran, einen Release-Build außerhalb des Debuggers auszuführen.)Wenn ja, kann jemand erklären, wie meine Schleife so viel schneller sein kann alsList.Contains()?Wenn nicht, kann jemand erklären, warum meine Schleife schneller ist?

Dies ist nicht nur für mich von akademischem Interesse, da ich Code schreibe, der mit großen Mengen numerischer Daten arbeitet und der so schnell wie möglich sein muss, und das ist die Art von Sache, die ich wissen muss. (Hinweis: Ja, ich profiliere Dinge und versuche nur Dinge zu optimieren, die optimiert werden müssen. Ich kenne die Probleme der vorzeitigen Optimierung.)

[BEARBEITEN]

Mir fällt ein, dass dies prozessorbezogen sein könnte. Alle Systeme, auf denen ich es ausprobiert habe, haben Intel-Prozessoren, wenn auch sehr unterschiedliche Modelle, von Quad-Core mit 3,8 GHz bis hin zu Pentium M-Single-Core mit 1,6 GHz ...

Für diejenigen unter Ihnen, die die Schleife langsamer sehen, verwenden Sie Intel-Prozessoren?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage