Grundsätzlich ist, wie in der Frage angegeben, die Reihenfolge der LINQ-Funktionen für die Leistung von Bedeutung ? Offensichtlich müssten die Ergebnisse noch identisch sein ...
Beispiel:
myCollection.OrderBy(item => item.CreatedDate).Where(item => item.Code > 3);
myCollection.Where(item => item.Code > 3).OrderBy(item => item.CreatedDate);
Beide geben mir die gleichen Ergebnisse zurück, befinden sich jedoch in einer anderen LINQ-Reihenfolge. Mir ist klar, dass das Nachbestellen einiger Artikel zu unterschiedlichen Ergebnissen führt, und ich mache mir darüber keine Sorgen. Mein Hauptanliegen ist es zu wissen, ob die Bestellung die Leistung beeinträchtigen kann, um die gleichen Ergebnisse zu erzielen. Und das nicht nur bei den 2 LINQ-Anrufen (OrderBy, Where), sondern bei allen LINQ-Anrufen.
c#
performance
linq
Michael
quelle
quelle
var query = myCollection.OrderBy(item => item.Code).Where(item => item.Code == 3);
.Antworten:
Dies hängt vom verwendeten LINQ-Anbieter ab. Für LINQ to Objects könnte dies sicherlich einen großen Unterschied machen. Angenommen, wir haben tatsächlich:
Dazu muss die gesamte Sammlung sortiert und dann gefiltert werden. Wenn wir eine Million Artikel hätten, von denen nur einer einen Code größer als 3 hätte, würden wir viel Zeit damit verschwenden, Ergebnisse zu bestellen, die weggeworfen würden.
Vergleichen Sie das mit der umgekehrten Operation, indem Sie zuerst filtern:
Dieses Mal bestellen wir nur die gefilterten Ergebnisse, was im Beispielfall "nur ein einziges Element, das zum Filter passt" viel effizienter ist - sowohl zeitlich als auch räumlich.
Es ist auch könnte einen Unterschied, ob die Abfrage ausgeführt werden korrekt ist oder nicht. Erwägen:
Das ist in Ordnung - wir wissen, dass wir niemals durch 0 teilen werden. Wenn wir jedoch die Reihenfolge vor dem Filtern ausführen, löst die Abfrage eine Ausnahme aus.
quelle
Ja.
Was genau dieser Leistungsunterschied ist, hängt jedoch davon ab, wie der zugrunde liegende Ausdrucksbaum vom LINQ-Anbieter bewertet wird.
Beispielsweise kann Ihre Abfrage beim zweiten Mal (mit der WHERE-Klausel zuerst) für LINQ-to-XML schneller ausgeführt werden, beim ersten Mal jedoch schneller für LINQ-to-SQL.
Um genau herauszufinden, was der Leistungsunterschied ist, möchten Sie höchstwahrscheinlich Ihre Anwendung profilieren. Wie immer bei solchen Dingen lohnt sich eine vorzeitige Optimierung jedoch normalerweise nicht. Möglicherweise sind andere Probleme als die LINQ-Leistung wichtiger.
quelle
In Ihrem speziellen Beispiel kann es dies die Leistung beeinflussen.
Erste Abfrage: Ihr
OrderBy
Anruf muss die gesamte Quellsequenz durchlaufen , einschließlich der Elemente mitCode
3 oder weniger. DieWhere
Klausel muss dann auch die gesamte geordnete Sequenz iterieren .Zweite Abfrage: Der
Where
Anruf beschränkt die Sequenz nur auf die Elemente, dieCode
größer als 3 sind. DerOrderBy
Anruf muss dann nur die reduzierte Sequenz durchlaufen, die vomWhere
Anruf zurückgegeben wird.quelle
In Linq-To-Objects:
Das Sortieren ist ziemlich langsam und verwendet
O(n)
Speicher.Where
Andererseits ist es relativ schnell und verwendet konstanten Speicher. Also mach esWhere
erste Mal geht es also schneller und bei großen Sammlungen deutlich schneller.Der reduzierte Speicherdruck kann ebenfalls erheblich sein, da Zuordnungen auf dem großen Objekthaufen (zusammen mit ihrer Sammlung) meiner Erfahrung nach relativ teuer sind.
quelle
Beachten Sie, dass dies nicht der Fall ist. Insbesondere die folgenden beiden Zeilen führen zu unterschiedlichen Ergebnissen (für die meisten Anbieter / Datensätze):
quelle
Es ist erwähnenswert, dass Sie sollten vorsichtig sein , wenn man bedenkt , wie eine LINQ - Abfrage zu optimieren. Wenn Sie beispielsweise die deklarative Version von LINQ verwenden, um Folgendes zu tun:
Wenn Sie aus irgendeinem Grund beschlossen haben, die Abfrage zu "optimieren", indem Sie den Durchschnitt zuerst in einer Variablen speichern, erhalten Sie nicht die gewünschten Ergebnisse:
Ich weiß, dass nicht viele Leute deklarativen LINQ für Objekte verwenden, aber es ist ein guter Denkanstoß.
quelle
Das hängt von der Relevanz ab. Angenommen, Sie haben nur sehr wenige Artikel mit Code = 3, dann funktioniert die nächste Bestellung mit einem kleinen Sammlungssatz, um die Bestellung nach Datum zu erhalten.
Wenn Sie hingegen viele Artikel mit demselben Erstellungsdatum haben, funktioniert die nächste Bestellung mit einem größeren Sammlungssatz, um die Bestellung nach Datum zu erhalten.
In beiden Fällen gibt es also einen Leistungsunterschied
quelle