wo Lambda gegen erstes Lambda

8

Angenommen, ich habe einige Zeichenfolgen:

%Vor%

Was ist der Unterschied zwischen:

%Vor%

Und:

%Vor%

Da Where () verzögert ist, sollte es die Ausführung nicht verlangsamen, oder?

    
micahhoover 10.01.2013, 16:00
quelle

3 Antworten

12

Die Leistungseinbußen bei der Verwendung von .Where(filter).First() anstatt .First(filter) sind normalerweise sehr klein.

Sie sind jedoch nicht gleich - Where erzeugt einen neuen Iterator, der First einfach ein Element von nehmen kann, während First(filter) Mikrooptimierung durch Verwendung nur einer Schleife und einer direkten Rückgabe, wenn filter übereinstimmt .

Während also beide Ansätze die gleiche Semantik haben und beide filter gleich oft ausführen (nur so oft wie nötig), muss First mit einem filter -Parameter kein intermediäres Iteratorobjekt und wahrscheinlich vermeidet einige sehr einfache Methodenaufrufe auch für diesen Iterator.

Mit anderen Worten, wenn Sie millionenfach Code ausführen, sehen Sie einen leichten Leistungsunterschied - aber nichts Großes; Ich würde mich nie Sorgen machen. Wann immer dieser kleine Leistungsunterschied wirklich wichtig ist, ist es viel besser, nur die (sehr einfache) foreach-with-if-Anweisung zu schreiben, die äquivalent ist und die zusätzlichen LINQ-Aufrufe und -Objektzuweisungen vermeidet - aber denken Sie daran, dass dies eine Mikrooptimierung ist selten brauchen.

Bearbeiten: Benchmark, der den Effekt demonstriert:

Das dauert 0,78 Sekunden:

%Vor%

Aber das dauert 1,41 Sekunden:

%Vor%

Während einfache Schleifen viel schneller sind (0,13 Sekunden):

%Vor%

Beachten Sie, dass dieser Benchmark nur so extreme Unterschiede zeigt, weil ich einen trivialen Filter und ein sehr kurzes nicht übereinstimmendes Präfix habe.

Aufgrund einiger schneller Experimente scheint der Unterschied größtenteils auf die Details zurückzuführen zu sein, aus denen Codepath genommen wird. Also, für Array's und List<> s ist die erste Variante tatsächlich schneller, wahrscheinlich eine spezielle Hülle in .Where für die Typen, die First nicht hat; Für benutzerdefinierte Iteratoren ist die zweite Version erwartungsgemäß ein kleines bisschen schneller.

Zusammenfassung:

.Where(...).First() ist ungefähr so ​​schnell wie .First(...) - stört es nicht, das eine oder andere als Optimierung zu wählen. In general .First(...) ist sehr wenig schneller, aber in einigen häufigen Fällen ist es langsamer. Wenn Sie diese Mikrooptimierung wirklich benötigen, verwenden Sie einfache Schleifen, die schneller sind als beide.

    
Eamon Nerbonne 10.01.2013, 16:09
quelle
1

Hier gibt es keine Unterschiede.

Calling Wobei zuerst ein Iterator zurückgegeben wird, der nicht verwendet wird, bis First mit dem Schleifen beginnt.

Wenn das Prädikat mit keinem Element übereinstimmt, wird dieselbe Ausnahme InvalidOperationException ausgelöst.

Der einzige Unterschied ist die Ausführlichkeit des Codes, also .Front ohne. Wo sollte bevorzugt werden

    
Sten Petrov 10.01.2013 16:09
quelle
1

Im speziellen Fall, wenn First und Where für string[] aufgerufen werden, sind die aufgerufenen Methoden die Erweiterungsmethoden Enumerable.Where und Enumerable.First .

Enumerable.Where macht das:

%Vor%

und der Konstruktor von WhereArrayIterator macht nur:

%Vor%

Es wird also nichts getan, außer einen Iterator zu erstellen.

Die erste First Methode ohne Prädikat tut das:

%Vor%

Das zweite First macht dies jedoch

%Vor%

Was bei einem Array so schnell ist wie direkter linearer Zugriff.
Zusammenfassend bedeutet dies, dass das Aufrufen von First(predicate) auf einem Array etwas schneller ist, durch einen nicht großen, aber dennoch erkennbaren Faktor. Dies gilt möglicherweise nicht für Listen und wird sicherlich nicht für IQueryable Objekte gelten, die eine völlig andere Geschichte sind.

Dies ist jedoch die Mikrooptimierung im schlimmsten Fall. Wenn dies nicht millionenfach geschieht, spart es nicht zu viele Sekunden. Selbst wenn ich das jetzt weiß, werde ich immer noch das verwenden, was klarer zu lesen und zu verstehen ist.

    
SWeko 10.01.2013 16:49
quelle

Tags und Links