LINQ-Abfragen sind faul . Das heißt der Code:
var things = mythings
.Where(x => x.IsSomeValue)
.Where(y => y.IsSomeOtherValue);
tut sehr wenig. Das ursprüngliche enumerable ( mythings
) wird nur dann aufgezählt, wenn das resultierende enumerable ( things
) verbraucht wird, z. B. von einer foreach
Schleife .ToList()
, oder .ToArray()
.
Wenn Sie aufrufen things.ToList()
, entspricht dies in etwa dem zuletzt genannten Code, möglicherweise mit einigem (normalerweise unbedeutendem) Overhead durch die Enumeratoren.
Ebenso, wenn Sie eine foreach-Schleife verwenden:
foreach (var t in things)
DoSomething(t);
Es ist in der Leistung ähnlich zu:
foreach (var t in mythings)
if (t.IsSomeValue && t.IsSomeOtherValue)
DoSomething(t);
Einige der Leistungsvorteile des Laziness-Ansatzes für Enumerables (im Gegensatz zum Berechnen aller Ergebnisse und zum Speichern in einer Liste) bestehen darin, dass nur sehr wenig Arbeitsspeicher belegt wird (da jeweils nur ein Ergebnis gespeichert wird) und keine signifikanten Fehler auftreten Kosten.
Wenn die Aufzählung nur teilweise erfolgt, ist dies besonders wichtig. Betrachten Sie diesen Code:
things.First();
Die Art und Weise, wie LINQ implementiert wird, mythings
wird nur bis zum ersten Element aufgezählt, das Ihren where-Bedingungen entspricht. Befindet sich dieses Element zu Beginn der Liste, kann dies eine enorme Leistungssteigerung bedeuten (z. B. O (1) anstelle von O (n)).