2010-12-14 10 views
74

Angesichts einer riesigen Sammlung von Objekten gibt es einen Leistungsunterschied zwischen den folgenden?LINQ-Ring: Beliebige() und Contains() für riesige Sammlungen

Collection.Contains:

myCollection.Contains(myElement) 

Enumerable.Any:

myCollection.Any(currentElement => currentElement == myElement) 
+6

Eine Sammlung von 10'000.000 Int's. Sieger ist das enthält für 300%. aber es ist wert, die unten erwähnten Abweichungen zu berücksichtigen. – SDReyes

+1

Dies scheint einen starken Kontrast zwischen den beiden zu zeigen: http://thedailywtf.com/Articles/State-of-the-UNION.aspx –

Antwort

98

Contains() ist eine Instanzmethode und ihre Leistung hängt weitgehend von der Sammlung selbst ab. Zum Beispiel ist Contains() in einer Liste O (n), während Contains() in einem HashSet O (1) ist.

Any() ist eine Erweiterungsmethode, die einfach durch die Auflistung geht und den Delegaten für jedes Objekt anwendet. Es hat daher eine Komplexität von O (n).

Any() ist flexibler, da Sie einen Delegaten übergeben können. Contains() kann nur ein Objekt akzeptieren.

+20

'Contains' ist auch eine Erweiterungsmethode gegen' IEnumerable '(obwohl einige Auflistungen ihre eigene 'Contains'-Instanzmethode haben). Wie Sie sagen, 'Any 'ist flexibler als' Contains', weil Sie ein benutzerdefiniertes Prädikat übergeben können, aber 'Contains' * könnte * etwas schneller sein, da kein Delegate-Aufruf für jedes Element ausgeführt werden muss. – LukeH

8

Es hängt von der Sammlung. Wenn Sie eine sortierte Sammlung haben, kann Contains eine intelligente Suche durchführen (binary, hash, b-tree usw.), während Sie bei Any() im Wesentlichen mit der Enumeration fortfahren, bis Sie sie finden (vorausgesetzt, LINQ to Objects)

Beachten Sie auch, dass in Ihrem Beispiel Any() den Operator "==" verwendet, der nach referenzieller Gleichheit sucht, während Contains IEquitable oder die Equals() -Methode verwendet, die überschrieben werden könnte.

+1

Mit. Sie können problemlos Eigenschaften vergleichen. Mit .Contains können Sie Objekte einfach vergleichen und Sie benötigen einen zusätzlichen IEqualityComparer, um Eigenschaften zu vergleichen. – msfanboy

+1

@msfanboy: Das stimmt, aber die Frage war speziell über die Leistung und zeigte das ganze Objekt zu vergleichen. Also ich denke nicht, dass es hier relevant ist. – tster

4

Ich nehme an, dass der Typ von myCollection hängt davon ab, wie Contains() implementiert ist. Wenn beispielsweise ein sortierter Binärbaum vorliegt, könnte er intelligenter suchen. Es kann auch den Hash des Elements berücksichtigen. Any() andererseits wird durch die Sammlung aufzählen, bis das erste Element, das die Bedingung erfüllt, gefunden wird. Es gibt keine Optimierungen, wenn das Objekt eine intelligentere Suchmethode hat.