2010-12-14 93 views
74

鑑於對象的巨大集合,以下是否存在性能差異?LINQ Ring:Any()vs Contains()for Large Collection

Collection.Contains

myCollection.Contains(myElement) 

Enumerable.Any

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

int的10'000.000的集合。贏家是包含300%。但值得考慮下面提到的差異。 – SDReyes 2010-12-15 01:51:59

+1

這似乎表明了兩者之間的鮮明對比:http://thedailywtf.com/Articles/State-of-the-UNION.aspx – 2014-08-18 20:16:35

回答

98

Contains()是一個實例方法,其性能在很大程度上取決於集合本身。例如,List上的Contains()是O(n),而HashSet上的Contains()是O(1)。

Any()是一個擴展方法,它將簡單地通過集合,將委託應用於每個對象。因此它具有O(n)的複雜性。

Any()更靈活,但因爲您可以傳遞委託。 Contains()只能接受一個對象。

+20

'Contains'也是針對IEnumerable 的擴展方法(儘管一些集合也有自己的Contains實例方法)。正如你所說,'Any'比'Contains'更靈活,因爲你可以將它傳遞給一個自定義的謂詞,但Contains可能稍微快一些,因爲它不需要爲每個元素執行委託調用。 – LukeH 2010-12-14 23:45:04

8

這取決於集合。如果你有一個有序的集合,那麼Contains可能會做一個智能搜索(二進制,散列,b-tree等),而使用Any(),你基本上都會列舉直到找到它(假設LINQ到對象)

還要注意,在你的例子中,Any()使用「==」運算符來檢查引用的相等性,而Contains將使用IEquitable或Equals()方法來重寫。

+1

隨着。任何你可以輕鬆地比較屬性。使用.Contains可以比較對象,並且需要額外的IEqualityComparer來比較屬性。 – msfanboy 2011-02-04 20:23:00

+1

@msfanboy:這是真的,但問題是具體關於性能,並顯示比較整個對象。所以我不認爲這是相關的。 – tster 2011-02-04 20:35:13

4

我想這將取決於myCollection的類型,它決定了Contains()的實現方式。例如,如果一個排序的二叉樹,它可以搜索更聰明。也可能需要考慮元素的哈希值。另一方面,Any()將枚舉整個集合,直到找到滿足條件的第一個元素。如果對象具有更智能的搜索方法,則沒有優化。