440 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.

12voto

Rik Punkte 27644

Das ist lächerlich. Es gibt keinen zwingenden Grund, die for-Schleife zu verbieten, sei es aus Leistungsgründen oder aus anderen Gründen.

Véase Jon Skeet's Blog für einen Leistungsvergleich und andere Argumente.

11voto

Meta-Knight Punkte 17142

In Fällen, in denen Sie mit einer Sammlung von Objekten arbeiten, foreach ist besser, aber wenn Sie eine Zahl inkrementieren, wird eine for Schleife ist besser.

Beachten Sie, dass Sie im letzten Fall etwa so vorgehen könnten:

foreach (int i in Enumerable.Range(1, 10))...

Aber die Leistung ist nicht besser, sondern sogar schlechter als bei einem for .

10voto

akuhn Punkte 26637

Das sollte Ihnen helfen:

public IEnumerator<int> For(int start, int end, int step) {
    int n = start;
    while (n <= end) {
        yield n;
        n += step;
    }
}

Verwendung:

foreach (int n in For(1, 200, 4)) {
    Console.WriteLine(n);
}

Um einen größeren Gewinn zu erzielen, können Sie drei Delegierte als Parameter nehmen.

9voto

NSFW Punkte 559

Auf diese Frage gibt es dieselben zwei Antworten wie auf die meisten Fragen nach dem "was ist schneller":

1) Wer nicht misst, kann nicht wissen.

2) (Weil...) Es kommt darauf an.

Es hängt davon ab, wie teuer die Methode "MoveNext()" im Vergleich zur Methode "this[int index]" für den Typ (oder die Typen) von IEnumerable ist, über den Sie iterieren werden.

Das "foreach"-Schlüsselwort ist eine Abkürzung für eine Reihe von Operationen - es ruft GetEnumerator() einmal auf dem IEnumerable auf, es ruft MoveNext() einmal pro Iteration auf, es führt eine Typüberprüfung durch und so weiter. Das, was sich am ehesten auf die Leistungsmessung auswirkt, sind die Kosten für MoveNext(), da es O(N) Mal aufgerufen wird. Vielleicht ist es billig, vielleicht aber auch nicht.

Das "for"-Schlüsselwort sieht vorhersehbarer aus, aber innerhalb der meisten "for"-Schleifen finden Sie etwas wie "collection[index]". Dies sieht wie eine einfache Array-Indizierung aus, ist aber eigentlich ein Methodenaufruf, dessen Kosten ganz von der Art der Sammlung abhängen, über die Sie iterieren. Wahrscheinlich ist es billig, vielleicht aber auch nicht.

Wenn die der Sammlung zugrundeliegende Struktur im Wesentlichen eine verknüpfte Liste ist, ist MoveNext spottbillig, aber der Indexer könnte O(N) Kosten verursachen, wodurch die tatsächlichen Kosten einer "for"-Schleife O(N*N) betragen.

9voto

Alex York Punkte 5342

Die Geschwindigkeitsunterschiede in einer for - und eine foreach -Schleife sind winzig, wenn man durch allgemeine Strukturen wie Arrays, Listen usw. eine Schleife durchläuft und eine LINQ Abfrage über die Sammlung ist fast immer etwas langsamer, obwohl es schöner zu schreiben ist! Wie die anderen Poster sagten, gehen für Ausdruckskraft eher als eine Millisekunde zusätzliche Leistung.

Was bisher noch nicht gesagt wurde, ist, dass, wenn ein foreach Schleife kompiliert wird, wird sie vom Compiler auf der Grundlage der Sammlung, über die sie iteriert, optimiert. Das heißt, wenn Sie nicht sicher sind, welche Schleife Sie verwenden sollen, sollten Sie die foreach Schleife - sie wird beim Kompilieren die beste Schleife für Sie erzeugen. Außerdem ist sie besser lesbar.

Ein weiterer entscheidender Vorteil des foreach Schleife ist, dass, wenn sich die Implementierung Ihrer Sammlung ändert (von einer int array zu einer List<int> zum Beispiel), dann ist Ihr foreach Schleife erfordert keine Änderungen am Code:

foreach (int i in myCollection)

Die obige Vorgehensweise ist unabhängig vom Typ der Sammlung gleich, während in Ihrer for Schleife, wird das Folgende nicht gebaut, wenn Sie die myCollection aus einer array zu einer List :

for (int i = 0; i < myCollection.Length, i++)

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