Ist Linq to Objects verketten, wo die Klausel VS && Leistungseinbußen so unbedeutend sind?

9

nach dieser Frage:
Sollte ich zwei" where "-Klauseln oder" & amp; & amp; "in meiner LINQ-Abfrage verwenden?

17319779 linq styling, Verkettung where Klausel vs und Operator Jon Skeet: Blogbeitrag

In den meisten Antworten wurde angegeben, dass die Linq To Objects -Leistung bei der Verkettung der where-Klausel vs & amp; & amp; in einem einzigen Lambda-Ausdruck ist vernachlässigbar, so dass es bis zu Ihrer Codierung Stil zu entscheiden, welche zu verwenden.

Ich habe mit der IL-Assembly angefangen, Sie können definitiv sehen, dass die Verkettung der WHERE-Klausel dazu führt, dass die Erweiterung zweimal aufgerufen wird und die Eingabe des zweiten Aufrufs das Ergebnis der ersten ist.

%Vor%

// Die IL

%Vor%

Dann starte ich eine einfache Benchmark auf Win7 .Net 3.5 und 4.0

%Vor%

Und die Ergebnisse:

%Vor%

Nach diesen Ergebnissen gibt es eine signifikante Leistungsverschlechterung, die auf eine Schlussfolgerung hinweist, dass Sie vermeiden sollten, where-Klausel in Linq an Objekte zu ketten.
Oder gibt es etwas, was mir fehlt?

    
makc 27.06.2013, 07:04
quelle

1 Antwort

3

Ja, es wäre ein guter Rat, zu versuchen, die Verkettung von .Where() -Klauseln übereinander zu vermeiden, wenn es ein Kinderspiel ist und Sie die Möglichkeit haben, wie in diesem Mikrobenchmark.

Beachten Sie, dass die LINQ-to-Objects-Implementierung von .NET schlau genug ist, die Prädikate für Sie zu kombinieren, wenn Sie dies tun. Es ist nicht so schlimm, wie es hätte sein können, aber das Ausführen des eleganten Ketten-Delegierten wird nicht so schnell oder so elegant sein wie das Ausführen eines einzelnen Delegaten mit der ganzen Logik darin.

Nehmen Sie jedoch an, Sie hätten eine beliebige Instanz von IEnumerable<T> , was möglicherweise das Ergebnis einer Methode .Where() ist, und Sie schreiben eine Methode, die sie nach einem Prädikat filtern muss.

Basieren Sie basierend auf den Ergebnissen dieses Microbenchmarks wirklich Ihre gesamte Codebasis, so dass Sie "where-Klausel in Linq an Objekte verketten" vermeiden können, oder fügen Sie einfach noch ein .Where() hinzu und verschieben Sie weiter mit deinem Leben?

Wie immer, wenn Sie tatsächliche Leistungstests für eine Anwendung mit Leistungsproblemen ausführen (dh die Leistung liegt außerhalb des Bereichs, der als "akzeptabel" definiert ist) und die Ergebnisse anzeigen, dass die Verkettung von .Where() -Klauseln ein Flaschenhals ist Sie sind vielleicht berechtigt, zu versuchen, zu überdenken, was vor sich geht.

Aus Neugierde habe ich auch die duplizierten "3" Klauseln in "4" Klauseln in RunTestAnd geändert, den Code auf meinem 4-Core Windows 8.1 x64 Rechner in .NET 4.5.1 ausgeführt (release mode, no debugger) , dann wurde es ausgeführt, nachdem die Zeile geändert wurde, die input zu:

initialisiert %Vor%

mit diesen Ergebnissen (Ausgabe massiert für Hübschheit, aber ich bürge dafür, dass dies die tatsächlichen Zahlen waren):

%Vor%

Was mir das nahelegt, ist, dass wenn Sie feststellen, dass Ihre 10-tiefe Kette von .Where() -Klauseln ein Engpass ist, es kein einfaches, einfaches Refactoring gibt und Ihr spezifisches Nutzungsszenario es erlaubt, PLINQ zu versuchen.

    
Joe Amenta 21.04.2014 10:10
quelle