Les requêtes LINQ sont paresseuses . Cela signifie que le code:
var things = mythings
.Where(x => x.IsSomeValue)
.Where(y => y.IsSomeOtherValue);
fait très peu. L' mythings
énumérateur original ( ) n'est énuméré que lorsque l'énumérateur résultant ( things
) est consommé, par exemple par une foreach
boucle,, .ToList()
ou .ToArray()
.
Si vous appelez things.ToList()
, il est à peu près équivalent à votre dernier code, avec peut-être une surcharge (généralement insignifiante) des énumérateurs.
De même, si vous utilisez une boucle foreach:
foreach (var t in things)
DoSomething(t);
Ses performances sont similaires à:
foreach (var t in mythings)
if (t.IsSomeValue && t.IsSomeOtherValue)
DoSomething(t);
Certains des avantages de performance de l'approche de la paresse pour les énumérables (par opposition au calcul de tous les résultats et à leur stockage dans une liste) sont qu'elle utilise très peu de mémoire (car un seul résultat est stocké à la fois) et qu'il n'y a pas de hausse significative -coût initial.
Si l'énumérable n'est que partiellement énuméré, cela est particulièrement important. Considérez ce code:
things.First();
La façon dont LINQ est implémenté mythings
ne sera énumérée que jusqu'au premier élément qui correspond à vos conditions where. Si cet élément est au début de la liste, cela peut être un énorme gain de performances (par exemple O (1) au lieu de O (n)).