Gibt es bei einer großen Sammlung von Objekten einen Leistungsunterschied zwischen den folgenden?
myCollection.Contains(myElement)
myCollection.Any(currentElement => currentElement == myElement)
c#
linq
performance
benchmarking
SDReyes
quelle
quelle
Antworten:
Contains()
ist eine Instanzmethode, deren Leistung weitgehend von der Sammlung selbst abhängt. Zum Beispiel istContains()
auf aList
O (n), währendContains()
auf aHashSet
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.quelle
Contains
ist auch eine Erweiterungsmethode gegenIEnumerable<T>
(obwohl einige Sammlungen auch eine eigeneContains
Instanzmethode haben). Wie Sie sagen,Any
ist es flexibler alsContains
weil Sie ihm ein benutzerdefiniertes Prädikat übergeben können, aberContains
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ährendContains
wird verwendenIEquatable<T>
oder dieEquals()
Methode, die außer Kraft gesetzt werden könnte.quelle
Ich nehme an, das würde von der Art abhängen,
myCollection
die vorschreibt, wieContains()
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.quelle
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 ....
quelle