451 Stimmen

Welche Schleife in .NET läuft schneller, "for" oder "foreach"?

In C#/VB.NET/.NET, welche Schleife läuft schneller, for o foreach ?

Seitdem ich gelesen habe, dass ein for Schleife arbeitet schneller als eine foreach Schleife a vor langer Zeit Ich nahm an, dass dies für alle Sammlungen, generischen Sammlungen, alle Arrays usw. gilt.

Ich habe Google durchforstet und einige Artikel gefunden, aber die meisten davon sind nicht schlüssig (lesen Sie die Kommentare zu den Artikeln) und haben ein offenes Ende.

Ideal wäre es, jedes Szenario aufzulisten und die beste Lösung dafür zu nennen.

Ein Beispiel (nur ein Beispiel dafür, wie es sein sollte):

  1. für die Iteration eines Arrays von 1000+ Zeichenketten - for ist besser als foreach
  2. zur Iteration über IList (nicht generische) Zeichenketten - foreach ist besser als for

Ein paar Referenzen im Internet für das gleiche gefunden:

  1. Ursprünglicher großer alter Artikel von Emmanuel Schanzer
  2. CodeProject FOREACH Vs. FOR
  3. Blog - Zum foreach oder nicht foreach das ist die Frage
  4. ASP.NET Forum - NET 1.1 C# for vs foreach

[Bearbeiten]

Abgesehen vom Aspekt der Lesbarkeit bin ich wirklich an Fakten und Zahlen interessiert. Es gibt Anwendungen, bei denen es auf die letzte Meile der Leistungsoptimierung ankommt.

4voto

Tad Donaghe Punkte 6640

Sie können ihm wirklich den Kopf verdrehen und stattdessen eine IQueryable .foreach-Schließung verwenden:

myList.ForEach(c => Console.WriteLine(c.ToString());

4voto

Diganta Kumar Punkte 3569

Ich fand die foreach Schleife, die sich durch eine List schneller . Siehe meine Testergebnisse unten. Im folgenden Code iteriere ich eine array der Größe 100, 10000 und 100000 getrennt mit for y foreach Schleife, um die Zeit zu messen.

enter image description here

private static void MeasureTime()
    {
        var array = new int[10000];
        var list = array.ToList();
        Console.WriteLine("Array size: {0}", array.Length);

        Console.WriteLine("Array For loop ......");
        var stopWatch = Stopwatch.StartNew();
        for (int i = 0; i < array.Length; i++)
        {
            Thread.Sleep(1);
        }
        stopWatch.Stop();
        Console.WriteLine("Time take to run the for loop is {0} millisecond", stopWatch.ElapsedMilliseconds);

        Console.WriteLine(" ");
        Console.WriteLine("Array Foreach loop ......");
        var stopWatch1 = Stopwatch.StartNew();
        foreach (var item in array)
        {
            Thread.Sleep(1);
        }
        stopWatch1.Stop();
        Console.WriteLine("Time take to run the foreach loop is {0} millisecond", stopWatch1.ElapsedMilliseconds);

        Console.WriteLine(" ");
        Console.WriteLine("List For loop ......");
        var stopWatch2 = Stopwatch.StartNew();
        for (int i = 0; i < list.Count; i++)
        {
            Thread.Sleep(1);
        }
        stopWatch2.Stop();
        Console.WriteLine("Time take to run the for loop is {0} millisecond", stopWatch2.ElapsedMilliseconds);

        Console.WriteLine(" ");
        Console.WriteLine("List Foreach loop ......");
        var stopWatch3 = Stopwatch.StartNew();
        foreach (var item in list)
        {
            Thread.Sleep(1);
        }
        stopWatch3.Stop();
        Console.WriteLine("Time take to run the foreach loop is {0} millisecond", stopWatch3.ElapsedMilliseconds);
    }

AKTUALISIERT

Nach dem Vorschlag von @jgauffin habe ich den Code von @johnskeet verwendet und festgestellt, dass die for Schleife mit array ist schneller als das Verfolgen,

  • Foreach-Schleife mit Array.
  • For-Schleife mit Liste.
  • Foreach-Schleife mit Liste.

Siehe meine Testergebnisse und den Code unten,

enter image description here

private static void MeasureNewTime()
    {
        var data = new double[Size];
        var rng = new Random();
        for (int i = 0; i < data.Length; i++)
        {
            data[i] = rng.NextDouble();
        }
        Console.WriteLine("Lenght of array: {0}", data.Length);
        Console.WriteLine("No. of iteration: {0}", Iterations);
        Console.WriteLine(" ");
        double correctSum = data.Sum();

        Stopwatch sw = Stopwatch.StartNew();
        for (int i = 0; i < Iterations; i++)
        {
            double sum = 0;
            for (int j = 0; j < data.Length; j++)
            {
                sum += data[j];
            }
            if (Math.Abs(sum - correctSum) > 0.1)
            {
                Console.WriteLine("Summation failed");
                return;
            }
        }
        sw.Stop();
        Console.WriteLine("For loop with Array: {0}", sw.ElapsedMilliseconds);

        sw = Stopwatch.StartNew();
        for (var i = 0; i < Iterations; i++)
        {
            double sum = 0;
            foreach (double d in data)
            {
                sum += d;
            }
            if (Math.Abs(sum - correctSum) > 0.1)
            {
                Console.WriteLine("Summation failed");
                return;
            }
        }
        sw.Stop();
        Console.WriteLine("Foreach loop with Array: {0}", sw.ElapsedMilliseconds);
        Console.WriteLine(" ");

        var dataList = data.ToList();
        sw = Stopwatch.StartNew();
        for (int i = 0; i < Iterations; i++)
        {
            double sum = 0;
            for (int j = 0; j < dataList.Count; j++)
            {
                sum += data[j];
            }
            if (Math.Abs(sum - correctSum) > 0.1)
            {
                Console.WriteLine("Summation failed");
                return;
            }
        }
        sw.Stop();
        Console.WriteLine("For loop with List: {0}", sw.ElapsedMilliseconds);

        sw = Stopwatch.StartNew();
        for (int i = 0; i < Iterations; i++)
        {
            double sum = 0;
            foreach (double d in dataList)
            {
                sum += d;
            }
            if (Math.Abs(sum - correctSum) > 0.1)
            {
                Console.WriteLine("Summation failed");
                return;
            }
        }
        sw.Stop();
        Console.WriteLine("Foreach loop with List: {0}", sw.ElapsedMilliseconds);
    }

4voto

Cade Roux Punkte 85601

In den meisten Fällen gibt es wirklich keinen Unterschied.

Normalerweise müssen Sie foreach immer dann verwenden, wenn Sie keinen expliziten numerischen Index haben, und Sie müssen for immer dann verwenden, wenn Sie keine iterierbare Sammlung haben (z.B. Iteration über ein zweidimensionales Array-Gitter in einem oberen Dreieck). Es gibt einige Fälle, in denen Sie eine Wahl haben.

Man könnte argumentieren, dass for-Schleifen ein wenig schwieriger zu pflegen sind, wenn magische Zahlen im Code auftauchen. Sie sollten sich zu Recht darüber ärgern, dass Sie keine for-Schleife verwenden können und stattdessen eine Sammlung aufbauen oder ein Lambda verwenden müssen, um eine Untersammlung aufzubauen, nur weil for-Schleifen verboten wurden.

4voto

colethecoder Punkte 1139

Es erscheint etwas seltsam, die Verwendung einer for-Schleife völlig zu verbieten.

Es gibt einen interessanten Artikel aquí die einen Großteil der Leistungsunterschiede zwischen den beiden Schleifen abdeckt.

Ich würde sagen, ich persönlich finde foreach etwas lesbarer als for-Schleifen, aber man sollte das Beste für die jeweilige Aufgabe verwenden und nicht extra langen Code schreiben, um eine foreach-Schleife einzubauen, wenn eine for-Schleife besser geeignet ist.

4voto

cjk Punkte 44394

Die beiden werden fast genau gleich ablaufen. Schreiben Sie einen Code, der beide verwendet, und zeigen Sie ihm dann die AWL. Die Berechnungen sollten vergleichbar sein, d.h. es sollte keinen Leistungsunterschied geben.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X