Was ist der Unterschied zwischen den folgenden Codezeilen bei Verwendung von LINQ für Sammlungen?
if(!coll.Any(i => i.Value))
und
if(!coll.Exists(i => i.Value))
Update 1
Wenn ich zerlege .Exists
, sieht es so aus, als gäbe es keinen Code.
Update 2
Weiß jemand, warum es für diesen keinen Code gibt?
c#
linq
collections
Anthony D.
quelle
quelle
Antworten:
Siehe Dokumentation
List.Exists (Objektmethode - MSDN)
Dies existiert seit .NET 2.0, also vor LINQ. Soll mit dem Prädikat- Delegaten verwendet werden , aber Lambda-Ausdrücke sind abwärtskompatibel. Auch nur List hat dies (nicht einmal IList)
IEnumerable.Any (Erweiterungsmethode - MSDN)
Dies ist neu in .NET 3.5 und verwendet Func (TSource, bool) als Argument. Daher sollte dies mit Lambda-Ausdrücken und LINQ verwendet werden.
Im Verhalten sind diese identisch.
quelle
List<>
Instanzmethoden aufgelistet habe .Der Unterschied besteht darin, dass Any eine Erweiterungsmethode für alle
IEnumerable<T>
in System.Linq.Enumerable definierten Methoden ist. Es kann auf jedem verwendet werdenIEnumerable<T>
Instanz verwendet werden.Exists scheint keine Erweiterungsmethode zu sein. Ich vermute, dass Coll vom Typ ist
List<T>
. Wenn ja Exists ist eine Instanzmethode, die Any sehr ähnlich funktioniert.Kurz gesagt , die Methoden sind im Wesentlichen gleich. Einer ist allgemeiner als der andere.
quelle
TLDR; In Bezug auf die Leistung
Any
scheint es langsamer zu sein (wenn ich dies richtig eingerichtet habe, um beide Werte fast gleichzeitig auszuwerten)Testlistengenerator:
Mit 10 Millionen Datensätzen
Mit 5 Millionen Datensätzen
Mit 1M Datensätzen
Mit 500k (Ich habe auch die Reihenfolge umgedreht, in der sie ausgewertet werden, um festzustellen, ob keine zusätzliche Operation mit der zuerst ausgeführten Operation verbunden ist.)
Mit 100.000 Datensätzen
Es scheint
Any
um die Größe 2 langsamer zu sein.Bearbeiten: Bei 5 und 10 Millionen Datensätzen habe ich die Art und Weise geändert, in der die Liste erstellt wird, und bin
Exists
plötzlich langsamer geworden, alsAny
dies impliziert, dass beim Testen etwas nicht stimmt.Neuer Testmechanismus:
Edit2: Ok, um jeglichen Einfluss von der Generierung von Testdaten auszuschließen, habe ich alles in eine Datei geschrieben und jetzt von dort gelesen.
10M
5M
1M
500k
quelle
Als Fortsetzung der Antwort von Matas zum Benchmarking.
TL / DR : Exists () und Any () sind gleich schnell.
Zunächst einmal: Das Benchmarking mit Stoppuhr ist nicht präzise ( siehe die Antwort von series0ne zu einem anderen, aber ähnlichen Thema ), aber weitaus präziser als DateTime.
Der Weg, um wirklich genaue Messwerte zu erhalten, ist die Verwendung von Leistungsprofilen. Eine Möglichkeit, ein Gefühl dafür zu bekommen, wie sich die Leistung der beiden Methoden gegenseitig misst, besteht darin, beide Methoden viele Male auszuführen und dann die jeweils schnellste Ausführungszeit zu vergleichen. Auf diese Weise spielt es wirklich keine Rolle, dass JITing und anderes Rauschen zu schlechten Messwerten führen (und das tut es auch ), da beide Ausführungen in gewissem Sinne " gleichermaßen falsch " sind.
Nach viermaliger Ausführung des obigen Codes (die wiederum 1 000
Exists()
undAny()
eine Liste mit 1 000 000 Elementen enthält) ist es nicht schwer zu erkennen, dass die Methoden ziemlich gleich schnell sind.Es gibt einen kleinen Unterschied, aber er ist zu klein, um nicht durch Hintergrundgeräusche erklärt zu werden. Meine Vermutung wäre, wenn man 10 000 oder 100 000 machen würde
Exists()
undAny()
stattdessen dieser kleine Unterschied mehr oder weniger verschwinden würde.quelle
Darüber hinaus funktioniert dies nur, wenn Value vom Typ bool ist. Normalerweise wird dies mit Prädikaten verwendet. Jedes Prädikat würde im Allgemeinen verwendet, um festzustellen, ob es ein Element gibt, das eine gegebene Bedingung erfüllt. Hier machen Sie einfach eine Map von Ihrem Element i zu einer bool-Eigenschaft. Es wird nach einem "i" gesucht, dessen Value-Eigenschaft wahr ist. Sobald dies erledigt ist, gibt die Methode true zurück.
quelle
Wenn Sie die Messungen korrigieren - wie oben erwähnt: Beliebig und Existiert und Durchschnitt addiert - erhalten wir folgende Ausgabe:
quelle