Gibt es bei einer großen Sammlung von Objekten einen Leistungsunterschied zwischen den folgenden?
myCollection.Contains(myElement)
myCollection.Any(currentElement => currentElement == myElement)
Gibt es bei einer großen Sammlung von Objekten einen Leistungsunterschied zwischen den folgenden?
myCollection.Contains(myElement)
myCollection.Any(currentElement => currentElement == myElement)
Antworten:
Contains()
ist eine Instanzmethode, deren Leistung weitgehend von der Sammlung selbst abhängt. Zum Beispiel ist Contains()
auf a List
O (n), während Contains()
auf a HashSet
O (1) ist.
Any()
ist eine Erweiterungsmethode und geht einfach die Sammlung durch und wendet den Delegaten auf jedes Objekt an. Es hat daher eine Komplexität von O (n).
Any()
ist jedoch flexibler, da Sie einen Delegaten übergeben können. Contains()
kann nur ein Objekt akzeptieren.
Contains
ist auch eine Erweiterungsmethode gegen IEnumerable<T>
(obwohl einige Sammlungen auch eine eigene Contains
Instanzmethode haben). Wie Sie sagen, Any
ist es flexibler als Contains
weil Sie ihm ein benutzerdefiniertes Prädikat übergeben können, aber Contains
möglicherweise etwas schneller, weil es nicht für jedes Element einen Delegatenaufruf durchführen muss.
All()
funktioniert ähnlich.
Das hängt von der Sammlung ab. Wenn Sie eine geordnete Sammlung haben, führen Sie Contains
möglicherweise eine intelligente Suche durch (Binär, Hash, B-Baum usw.), während Sie bei `Any () grundsätzlich mit der Aufzählung beschäftigt sind, bis Sie sie finden (unter der Annahme von LINQ-to-Objects). .
Beachten Sie auch , dass in Ihrem Beispiel, Any()
das unter Verwendung von ==
Operator, der für Referenz Gleichheit überprüfen wird, während Contains
wird verwenden IEquatable<T>
oder die Equals()
Methode, die außer Kraft gesetzt werden könnte.
Ich nehme an, das würde von der Art abhängen, myCollection
die vorschreibt, wie Contains()
implementiert wird. Wenn zum Beispiel ein sortierter Binärbaum, könnte er intelligenter suchen. Es kann auch den Hash des Elements berücksichtigen. Any()
Auf der anderen Seite wird die Sammlung aufgelistet, bis das erste Element gefunden ist, das die Bedingung erfüllt. Es gibt keine Optimierungen dafür, ob das Objekt eine intelligentere Suchmethode hatte.
Contains () ist auch eine Erweiterungsmethode, die schnell funktionieren kann, wenn Sie sie richtig verwenden. Zum Beispiel:
var result = context.Projects.Where(x => lstBizIds.Contains(x.businessId)).Select(x => x.projectId).ToList();
Dies gibt die Abfrage
SELECT Id
FROM Projects
INNER JOIN (VALUES (1), (2), (3), (4), (5)) AS Data(Item) ON Projects.UserId = Data.Item
während Any () andererseits immer durch das O (n) iteriert.
Hoffe das wird funktionieren ....