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 ListO (n), während Contains()auf a HashSetO (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.
Containsist auch eine Erweiterungsmethode gegen IEnumerable<T>(obwohl einige Sammlungen auch eine eigene ContainsInstanzmethode haben). Wie Sie sagen, Anyist es flexibler als Containsweil 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 Containsmö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 Containswird 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, myCollectiondie 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 ....