En C #/VB.NET/.NET, quelle boucle est la plus rapide, for
ou foreach
?
Depuis que j'ai lu qu'une boucle for
fonctionnait plus rapidement qu'une boucle foreach
un il y a longtemps , je pensais que cela était vrai pour toutes les collections, les collections génériques, tous les tableaux, etc.
J'ai parcouru Google et trouvé quelques articles, mais la plupart ne sont pas concluants (lisez les commentaires sur les articles) et ouverts.
L'idéal serait de répertorier chaque scénario et de trouver la meilleure solution.
Par exemple (juste un exemple de comment cela devrait être):
for
vaut mieux que foreach
IList
chaînes (non génériques) - foreach
est meilleur que for
Quelques références trouvées sur le web pour la même chose:
foreach
ou pas à foreach
, telle est la questionfor
vs foreach
[Modifier]
Outre l'aspect de la lisibilité, je m'intéresse beaucoup aux faits et aux chiffres. Il existe des applications dans lesquelles le dernier kilomètre d'optimisation des performances est important.
Patrick Smacchia blogué à ce sujet le mois dernier, avec les conclusions suivantes:
- les boucles for list sur sont un peu plus de 2 fois moins chères que les boucles foreach sur List.
- La mise en boucle sur un tableau coûte environ 2 fois moins cher que sur la liste.
- En conséquence, boucler sur un tableau en utilisant est 5 fois moins cher que sur Boucle sur List en utilisant foreach (ce que je pense, c’est ce que nous faisons tous).
Les boucles foreach
démontrent une intention plus spécifique que les boucles for
.
L'utilisation d'une boucle foreach
montre à toute personne utilisant votre code que vous envisagez de modifier quelque chose pour chaque membre d'une collection, quelle que soit sa place dans la collection. Il montre également que vous ne modifiez pas la collection d'origine (et lève une exception si vous essayez de le faire).
L’autre avantage de foreach
est qu’il fonctionne sur n’importe quel IEnumerable
, où for
n’a de sens que pour IList
, où chaque élément a effectivement un index.
Toutefois, si vous devez utiliser l'index d'un élément, vous devez bien entendu être autorisé à utiliser une boucle for
. Mais si vous n'avez pas besoin d'utiliser un index, en avoir un ne fait qu'encombrer votre code.
Autant que je sache, il n'y a pas d'incidence significative sur les performances. Dans le futur, il sera peut-être plus facile d'adapter le code en utilisant foreach
pour qu'il s'exécute sur plusieurs cœurs, mais ce n'est pas un sujet de préoccupation pour le moment.
Premièrement, une demande reconventionnelle à réponse de Dmitry . Pour les tableaux, le compilateur C # émet en grande partie le même code pour foreach
que pour une boucle équivalente for
. Cela explique pourquoi, pour ce repère, les résultats sont fondamentalement les mêmes:
using System;
using System.Diagnostics;
using System.Linq;
class Test
{
const int Size = 1000000;
const int Iterations = 10000;
static void Main()
{
double[] data = new double[Size];
Random rng = new Random();
for (int i=0; i < data.Length; i++)
{
data[i] = rng.NextDouble();
}
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: {0}", sw.ElapsedMilliseconds);
sw = Stopwatch.StartNew();
for (int 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: {0}", sw.ElapsedMilliseconds);
}
}
Résultats:
For loop: 16638
Foreach loop: 16529
Ensuite, confirmez que le point de Greg sur le type de collection est important - changez le tableau en List<double>
dans ce qui précède, et vous obtiendrez des résultats radicalement différents. Non seulement il est nettement plus lent en général, mais il devient beaucoup plus lent que chaque accès par index. Ceci dit, je préférerais toujours presque toujours préférer foreach à une boucle for, ce qui simplifierait le code - car la lisibilité est presque toujours importante, alors que micro- l'optimisation l'est rarement.
Chaque fois qu'il y a des arguments sur les performances, il vous suffit d'écrire un petit test afin de pouvoir utiliser des résultats quantitatifs pour étayer votre cas.
Utilisez la classe StopWatch et répétez quelque chose quelques millions de fois, pour plus de précision. (Cela pourrait être difficile sans une boucle for):
using System.Diagnostics;
//...
Stopwatch sw = new Stopwatch()
sw.Start()
for(int i = 0; i < 1000000;i ++)
{
//do whatever it is you need to time
}
sw.Stop();
//print out sw.ElapsedMilliseconds
Les doigts croisés sur les résultats de cette série montrent que la différence est négligeable et que vous pouvez aussi bien faire ce qui se passe dans le code le plus facile à gérer
Ce sera toujours proche. Pour un tableau, parfoisfor
est légèrement plus rapide, mais foreach
est plus expressif et offre LINQ, etc. En général, restez avec foreach
.
De plus, foreach
peut être optimisé dans certains scénarios. Par exemple, une liste liée peut être terrible pour l'indexeur, mais rapide pour foreach
. En fait, la norme LinkedList<T>
ne propose même pas d'indexeur pour cette raison.
Je suppose que cela ne sera probablement pas significatif dans 99% des cas, alors pourquoi choisiriez-vous le plus rapide au lieu du plus approprié (comme dans le plus facile à comprendre/à maintenir)?
Il y a de très bonnes raisons de préfèreforeach
boucles sur for
boucles. Si vous pouvez utiliser une boucle foreach
, votre patron a raison de le faire.
Cependant, chaque itération ne passe pas simplement par une liste, une par une. S'il interdit , oui, c'est faux.
Si j'étais vous, ce que je ferais est transformez toutes vos boucles naturelles en récursion. Cela lui apprendrait, et c’est aussi un bon exercice mental pour vous.
Il est peu probable qu’il y ait une énorme différence de performances entre les deux. Comme toujours, face à un "qui est plus rapide?" question, vous devriez toujours penser "je peux mesurer cela."
Ecrivez deux boucles qui font la même chose dans le corps de la boucle, exécutez-les et chronométrez-les toutes les deux, et voyez quelle est la différence de vitesse. Faites cela avec un corps presque vide et un corps de boucle similaire à ce que vous allez réellement faire. Essayez également avec le type de collection que vous utilisez, car différents types de collections peuvent avoir différentes caractéristiques de performances.
Jeffrey Richter sur TechEd 2005:
"J'ai appris au fil des ans que le compilateur C # était un menteur pour moi." .. "Il ment à propos de beaucoup de choses." .. "Comme quand vous faites une boucle foreach ..." ... "... c'est une petite ligne de code que vous écrivez, mais ce que le compilateur C # crache pour faire cela est phénoménal. Il crée un try/finally block in, à l'intérieur du bloc finally, votre variable est convertie en une interface IDisposable et, si la conversion réussit, elle appelle la méthode Dispose, à l'intérieur de la boucle, elle appelle à plusieurs reprises la propriété Current et la méthode MoveNext, des objets sont créés sous les couvertures.Beaucoup de gens utilisent foreach parce que c’est très facile à coder, très facile à faire .. ".." foreach n’est pas très performant en termes de performances, si vous effectuez une itération sur une collection à l’aide de la notation entre crochets, juste en faisant un index, c'est beaucoup plus rapide, et cela ne crée aucun objet sur le tas ... "
Webcast à la demande: http://msevents.Microsoft.com/CUI/WebCastEventDetails.aspx?EventID=1032292286&EventCategory=3&culture=en-US&CountryCode=US
C'est ridicule. Il n'y a aucune raison impérieuse d'interdire la boucle for, performance ou autre.
Voir blog de Jon Skeet pour un benchmark de performance et d'autres arguments.
Dans les cas où vous travaillez avec une collection d'objets, foreach
est préférable, mais si vous incrémentez un nombre, une boucle for
est préférable.
Notez que dans le dernier cas, vous pourriez faire quelque chose comme:
foreach (int i in Enumerable.Range(1, 10))...
Mais il n’est certainement pas plus performant, il a en fait une performance inférieure à celle d’un for
.
Cela devrait vous sauver:
public IEnumerator<int> For(int start, int end, int step) {
int n = start;
while (n <= end) {
yield n;
n += step;
}
}
Utilisation:
foreach (int n in For(1, 200, 4)) {
Console.WriteLine(n);
}
Pour une plus grande victoire, vous pouvez prendre trois délégués comme paramètres.
Cela a les mêmes réponses que la plupart des questions "ce qui est plus rapide":
1) Si vous ne mesurez pas, vous ne savez pas.
2) (Parce que ...) Cela dépend.
Cela dépend du coût de la méthode "MoveNext ()", par rapport au coût de la méthode "this [int index]", pour le type (ou les types) de IEnumerable sur lequel vous allez effectuer une itération.
Le mot clé "foreach" est un raccourci pour une série d'opérations: il appelle GetEnumerator () une fois sur IEnumerable, MoveNext () une fois par itération, vérifie le type, etc. Le coût de MoveNext () est le plus susceptible d’avoir une incidence sur les mesures de performance, car il est appelé O(N) fois. Peut-être que c'est bon marché, mais peut-être que non.
Le mot clé "for" semble plus prévisible, mais dans la plupart des boucles "for", vous trouverez quelque chose comme "collection [index]". Cela ressemble à une simple opération d'indexation de tableau, mais il s'agit en fait d'un appel de méthode dont le coût dépend entièrement de la nature de la collection sur laquelle vous effectuez une itération. C'est probablement bon marché, mais peut-être que non.
Si la structure sous-jacente de la collection est essentiellement une liste chaînée, MoveNext est très économique, mais l'indexeur peut avoir un coût de O(N), ce qui donne le coût réel d'une boucle "pour" O (N * N). .
"Y a-t-il des arguments que je pourrais utiliser pour m'aider à le convaincre que la boucle est acceptable?"
Non, si votre supérieur hiérarchique vous dit ce que le langage de programmation doit utiliser, vous ne pouvez vraiment rien en dire. Pardon.
Les différences de vitesse dans une boucle for
- et une boucle foreach
- sont minimes lorsque vous parcourez des structures courantes telles que des tableaux, des listes, etc. et que vous effectuez une requête LINQ
sur la collection. est presque toujours un peu plus lent, même s’il est plus agréable d’écrire! Comme les autres affiches l'ont dit, privilégiez l'expressivité plutôt qu'une milliseconde de performances supplémentaires.
Ce qui n'a pas été dit jusqu'à présent, c'est que lorsqu'une boucle foreach
est compilée, elle est optimisée par le compilateur en fonction de la collection sur laquelle elle est itérative. Cela signifie que lorsque vous ne savez pas quelle boucle utiliser, vous devez utiliser la boucle foreach
- elle générera la meilleure boucle pour vous lorsqu'elle sera compilée. C'est plus lisible aussi.
Un autre avantage clé de la boucle foreach
est que, si votre implémentation de collection change (d’un int array
à un List<int>
par exemple), votre boucle foreach
ne nécessitera aucune changements de code:
foreach (int i in myCollection)
Ce qui précède est le même quel que soit le type de votre collection. Tandis que dans votre boucle for
, le suivant ne sera pas généré si vous avez changé myCollection
d’un array
à un List
:
for (int i = 0; i < myCollection.Length, i++)
Cela dépend probablement du type de collection que vous énumérez et de l'implémentation de son indexeur. En général cependant, utiliser foreach
sera probablement une meilleure approche.
En outre, cela fonctionnera avec n'importe quel IEnumerable
- pas seulement avec les indexeurs.
Chaque construction de langage a une heure et un lieu appropriés pour l’utilisation. Il y a une raison pour laquelle le langage C # a quatre instructions d'itération distinctes - chacune y est pour un but spécifique et a un usage approprié.
Je recommande de vous asseoir avec votre patron et d'essayer d'expliquer de manière rationnelle pourquoi une boucle for
a un but. Il arrive parfois qu'un bloc d'itération for
décrit plus clairement un algorithme qu'une itération foreach
. Lorsque cela est vrai, il convient de les utiliser.
Je voudrais également signaler à votre patron que la performance n’est pas et ne devrait pas être un problème pratique; c’est plus une question d’expression de l’algorithme de manière succincte, cohérente et facile à gérer. Les micro-optimisations comme celle-ci passent complètement à côté de l'optimisation des performances, car tout avantage réel en termes de performances proviendra de la refonte, de la refactorisation et de l'algorithmique algorithmiques.
Si, après une discussion rationnelle, il y a toujours cette vision autoritaire, c'est à vous de décider comment procéder. Personnellement, je ne serais pas heureux de travailler dans un environnement où la pensée rationnelle est découragée et envisagerais de changer de poste chez un autre employeur. Cependant, je recommande fortement de discuter avant de s’énerver - il peut simplement y avoir un simple malentendu.
vous pouvez lire à ce sujet dans Deep .NET - partie 1 Itération
il couvre les résultats (sans la première initialisation) depuis le code source .NET jusqu'au démontage.
par exemple - Itération de tableau avec une boucle foreach:
Si for
est plus rapide que foreach
est vraiment hors de propos. Je doute sérieusement que choisir l’un sur l’autre aura un impact significatif sur votre performance.
Le meilleur moyen d'optimiser votre application consiste à profiler le code réel. Cela identifiera les méthodes qui représentent le plus de travail/temps. Optimisez les premiers. Si les performances ne sont toujours pas acceptables, répétez la procédure.
En règle générale, je vous conseillerais d'éviter les micro-optimisations car elles ne donneront que rarement des gains significatifs. La seule exception est l’optimisation des chemins chauds identifiés (c.-à-d. Si votre profilage identifie quelques méthodes très utilisées, il peut être judicieux de les optimiser de manière approfondie).
C’est ce que vous faites à l’intérieur la boucle qui affecte les performances, pas la structure de boucle réelle (en supposant que votre cas n’est pas trivial).
Les deux fonctionneront presque exactement de la même manière. Écrivez un code pour utiliser les deux, puis montrez-lui le IL. Il devrait montrer des calculs comparables, ce qui signifie aucune différence de performance.
Visser vraiment avec sa tête et aller pour une fermeture IQueryable .foreach à la place:
myList.ForEach (c => Console.WriteLine (c.ToString ());
LOL
for a une logique plus simple à implémenter, donc c'est plus rapide que foreach.
Dans la plupart des cas, il n'y a vraiment pas de différence.
En règle générale, vous devez toujours utiliser foreach lorsque vous ne disposez pas d'un index numérique explicite, mais également lorsque vous n'avez pas réellement de collection itérable (par exemple, une itération sur une grille de tableau à deux dimensions dans un triangle supérieur). . Il y a des cas où vous avez le choix.
On pourrait dire que les boucles for peuvent être un peu plus difficiles à maintenir si des nombres magiques commencent à apparaître dans le code. Vous devriez avoir raison de ne pas pouvoir utiliser une boucle for et devoir créer une collection ou utiliser un lambda pour créer une sous-collection, car les boucles for ont été interdites.
Jeffrey Richter a parlé de la différence de performance entre for et foreach dans un podcast récent: http://pixel8.infragistics.com/shows/everything.aspx#Episode:9317
J'ai trouvé la boucle foreach
qui itère dans un List
plus rapide. Voir mes résultats de test ci-dessous. Dans le code ci-dessous, j'itère une array
de taille 100, 10000 et 100000 séparément en utilisant la boucle for
et foreach
pour mesurer le temps.
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);
}
Après la suggestion de @jgauffin, j’ai utilisé le code @johnskeet et découvert que la boucle for
avec array
est plus rapide que celle qui suit,
Voir mes résultats de test et le code ci-dessous,
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);
}
Sauf si vous êtes dans un processus d'optimisation de vitesse spécifique, je dirais que vous devez utiliser la méthode qui produit le plus facilement la lecture et la maintenance du code.
Si un itérateur est déjà configuré, comme avec l'une des classes de la collection, foreach est une bonne option. Et si vous parcourez une plage entière, alors c'est probablement plus propre.
Il semble un peu étrange d'interdire totalement l'utilisation de quelque chose comme une boucle for.
Il y a un article intéressant ici qui couvre beaucoup de différences de performances entre les deux boucles.
Personnellement, je trouve que foreach est un peu plus lisible pour les boucles mais que vous devriez utiliser le meilleur pour le travail à effectuer et ne pas avoir à écrire un code très long pour inclure une boucle foreach si une boucle for est plus appropriée.
Je ne m'attendrais pas à ce que quelqu'un trouve une "énorme" différence de performances entre les deux.
Je suppose que la réponse dépend du fait que la collection à laquelle vous essayez d'accéder dispose d'une implémentation d'accès plus rapide pour l'indexeur ou d'un accès plus rapide pour IEnumerator. IEnumerator utilisant souvent l'indexeur et ne conservant qu'une copie de la position d'index actuelle, je m'attendrais à ce que l'accès de l'énumérateur soit au moins aussi lent ou plus lent que l'accès direct à l'index, mais pas beaucoup.
Bien sûr, cette réponse ne tient pas compte des optimisations que le compilateur peut implémenter.
Gardez à l'esprit que les boucles for et loop foreach ne sont pas toujours équivalentes. Les énumérateurs de liste lèveront une exception si la liste change, mais vous ne recevrez pas toujours cet avertissement avec une boucle for normale. Vous pouvez même obtenir une exception différente si la liste change au mauvais moment.
Je l'ai testé il y a quelque temps, avec pour résultat qu'une boucle for
est beaucoup plus rapide qu'une boucle foreach
. La cause est simple, la boucle foreach
doit d'abord instancier un IEnumerator
pour la collection.
Dans mon projet sous Windows Mobile, j'ai utilisé une boucle for
pour une collection de contrôles. Cela a pris 100 ms pour 20 contrôles! Une boucle foreach
n'a utilisé que 4 ms. C'était un problème de performance ...
Je suis tombé sur un cas où foreach beaucoup plus vite que pour
pourquoi foreach est plus rapide que for boucle lors de la lecture des lignes richtextbox
J'ai eu un cas similaire au PO dans cette question.
Une zone de texte lisant environ 72 000 lignes et j’accédais à la propriété Lines (qui est en réalité une méthode d’acquisition). (Et apparemment, souvent, dans winforms, il existe des méthodes getter qui ne sont pas O (1). Je suppose que c'est O (n), donc plus la zone de texte est grande, plus il faut longtemps pour obtenir une valeur de cette propriété. La boucle que j’avais avec l’opération il y avait for(int i=0;i<textBox1.lines.length;i++) str=textBox1.Lines[i]
, et c’était vraiment très lente car il lisait l’ensemble de la zone de texte chaque fois qu’il lisait une ligne et lisait l’ensemble du texte à chaque vérification de la condition.
Jon Skeet montre que vous pouvez accéder à la propriété Lines une seule fois (pas une seule fois par itération, une seule fois). Plutôt que deux fois à chaque itération (ce qui représente une tonne de fois). Ne string [] strarrlines = textBox1.Lines; et boucle à travers les strarrlines.
Mais certainement une boucle for dans une forme assez intuitive et accéder à la propriété Lines, est très inefficace
for (int i = 0; i < richTextBox.Lines.Length; i++)
{
s = richTextBox.Lines[i];
}
pour une zone de texte, ou une zone de texte riche, c'est super lent.
Le PO, qui a testé cette boucle sur une zone de texte enrichie, a constaté qu '"avec 15 000 lignes.for, il fallait 8 minutes pour que la boucle se réduise à 15 000 lignes. Pour chaque boucle, il fallait une fraction de seconde pour l'énumérer".
Le PO sur ce lien a trouvé que cette méthode était bien plus efficace que sa boucle (identique) mentionnée ci-dessus. Comme je l'ai fait.
String s=String.Empty;
foreach(string str in txtText.Lines)
{
s=str;
}
J'ai mentionné ces détails en fonction de la rapidité de la collecte pour et pour chaque.
List -For Loop est légèrement plus rapide que Foreach Loop
ArrayList - For Loop est environ deux fois plus rapide que Foreach Loop.
Tableau - Les deux sont à la même vitesse. Mais Foreach Loop semble être un peu plus rapide.
Ben Watson, auteur de "Writing Code .NET hautes performances":
"L'optimisation importera-t-elle à votre programme? Seulement si votre programme est lié au CPU et que l'itération de la collecte est une partie essentielle de votre traitement. Comme vous le verrez, il existe des moyens de nuire à votre performance si vous ne faites pas attention, Ma philosophie est la suivante: la plupart des gens n’ont jamais besoin de le savoir, mais si vous le savez, il est important de comprendre toutes les couches du système pour pouvoir faire des choix intelligents " .
L'explication la plus détaillée peut être trouvée ici: http://www.codeproject.com/Articles/844781/Digging-Into-NET-Loop-Performance-Bounds-checking
Au moins, je n'ai vu aucun de mes collègues ou de mes supérieurs hiérarchiques affirmer cela, c'est ridicule compte tenu du fait qu'il n'y a pas de différence de vitesse significative entre for
et foreach
. Il en va de même s'il demande à l'utiliser dans tous les cas!
À partir de .NET Framework 4, vous pouvez également utiliser Parallel.For et Parallel.ForEach comme décrit ci-dessous: Boucle de lecture multithreading C # avec Parallel.For ou Parallel.ForEach
Je pense que pour est légèrement plus rapide que pour chaque dans la plupart des cas, mais cela manque vraiment l’essentiel. Une chose que je n'ai pas encore vue est que, dans le scénario dont vous parlez (c'est-à-dire une application Web à volume élevé), la différence de performances entre pour et pour chaque n'aura aucune incidence sur les performances du site. Vous allez être limité par le temps de demande/réponse et le temps de base de données, pas par opposition à foreach.
Cela dit, je ne comprends pas votre aversion pour la foreach. À mon avis, foreach est généralement plus clair dans les situations où l’un ou l’autre pourrait être utilisé. Je réserve habituellement pour des situations où je dois parcourir une collection d'une manière laide et non standard.
J'avais besoin d'analyser des données volumineuses en utilisant trois boucles imbriquées (sur List<MyCustomType>
). J'ai pensé, en utilisant le post de Rob Fonseca-Ensor ci-dessus, qu'il serait intéressant de chronométrer et de comparer la différence en utilisant for et foreach.
La différence était la suivante: les foreach (trois foreach imbriqués comme foreach {foreach {forech {}}} faisaient le travail en 171.441 secondes où comme pour (pour {pour {pour {}}}) 158,616 secondes.
Maintenant, 13 secondes, c’est environ 13% réduction du temps nécessaire pour le faire - ce qui est assez important pour moi. Cependant, foreach est nettement plus lisible que l’utilisation de trois index-fors ...
Je suggérerais de lire this pour une réponse spécifique. La conclusion de l'article est que l'utilisation de la boucle for est généralement meilleure et plus rapide que la boucle foreach.