LINQ रिंग: विशाल संग्रह के लिए कोई भी () बनाम शामिल ()


103

वस्तुओं के विशाल संग्रह को देखते हुए, निम्नलिखित के बीच एक प्रदर्शन अंतर है?

संग्रह

myCollection.Contains(myElement)

Enumerable.Any :

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

7
इंट का 10'000.000 का संग्रह। विजेता में 300% शामिल है। लेकिन यह नीचे उल्लिखित संस्करण पर विचार करने के लिए योग्य है।
SDReyes

1
ऐसा लगता है कि दोनों के बीच एक विपरीत स्थिति है: thedailywtf.com/Articles/State-of-the-UNION.aspx
डेविड पीटरसन

जवाबों:


143

Contains()एक उदाहरण विधि है, और इसका प्रदर्शन काफी हद तक संग्रह पर ही निर्भर करता है। उदाहरण के लिए, Contains()एक Listओ (एन) पर है, जबकि Contains()एक HashSetओ (1) पर है।

Any()एक विस्तार विधि है, और बस संग्रह के माध्यम से जाना होगा, प्रत्येक वस्तु पर प्रतिनिधि को लागू करना। इसलिए इसमें O (n) की जटिलता है।

Any()हालांकि आप एक प्रतिनिधि को पास कर सकते हैं लेकिन अधिक लचीला है। Contains()केवल एक वस्तु को स्वीकार कर सकते हैं।


27
Containsके विरुद्ध एक विस्तार विधि भी है IEnumerable<T>(हालाँकि कुछ संग्रहों की अपनी Containsआवृत्ति विधि भी है)। जैसा कि आप कहते हैं, Anyकी तुलना में अधिक लचीला है Containsक्योंकि आप इसे एक कस्टम विधेय पास कर सकते हैं, लेकिन थोड़ा तेज Contains हो सकता है क्योंकि इसे प्रत्येक तत्व के लिए एक प्रतिनिधि मंगलाचरण करने की आवश्यकता नहीं है।
लूका

1
क्या कोई () संग्रह में सभी वस्तुओं पर ऑपरेशन करता है या यह पहले मैच के साथ समाप्त होता है?
क्वार्कली

1
स्रोत के अनुसार कम से कम , यह पहले मैच पर रुक जाता है। All()इसी तरह काम करता है।
इतिने डे मार्टेल

13

यह संग्रह पर निर्भर करता है। यदि आपके पास एक ऑर्डर किया हुआ संग्रह है, तो Containsएक स्मार्ट खोज (बाइनरी, हैश, बी-ट्री, इत्यादि) कर सकते हैं, जबकि `कोई () के साथ आप मूल रूप से एन्यूमरेटिंग के साथ अटक जाते हैं जब तक कि आप इसे नहीं पाते (LINQ-to-Objects को ग्रहण करते हुए) ।

यह भी ध्यान दें कि आपके उदाहरण में, ऑपरेटर Any()का उपयोग कर रहा है ==जो संदर्भात्मक समानता के लिए जांच करेगा, जबकि Containsउपयोग IEquatable<T>या Equals()विधि होगी, जिसे अस्वीकार किया जा सकता है।


4
के साथ। किसी भी आप आसानी से गुणों की तुलना कर सकते हैं। .Contains के साथ आप केवल वस्तुओं की तुलना कर सकते हैं और गुणों की तुलना करने के लिए आपको एक अतिरिक्त IEqualityComparer की आवश्यकता होगी।
msfanboy

1
@msfanboy: यह सच है, लेकिन सवाल विशेष रूप से प्रदर्शन के बारे में था और पूरी वस्तु की तुलना करते हुए दिखाया गया था। इसलिए मुझे नहीं लगता कि यह यहां प्रासंगिक है।
तार

4

मुझे लगता है कि के प्रकार पर निर्भर करेगा लगता है myCollectionजो तय कर कैसे है Contains()कार्यान्वित किया जाता है। यदि उदाहरण के लिए एक सॉर्ट किए गए बाइनरी ट्री, यह होशियार खोज सकता है। इसके अलावा, यह तत्व के हैश को ध्यान में रख सकता है। Any()दूसरी ओर संग्रह के माध्यम से गणना करेगा जब तक कि पहला तत्व जो स्थिति को संतुष्ट करता है वह नहीं मिला। यदि ऑब्जेक्ट के पास कोई स्मार्ट खोज विधि है, तो इसके लिए कोई अनुकूलन नहीं हैं।


0

सम्‍मिलित () भी एक विस्‍तार विधि है जो सही तरीके से उपयोग करने पर तेजी से काम कर सकती है। पूर्व के लिए:

var result = context.Projects.Where(x => lstBizIds.Contains(x.businessId)).Select(x => x.projectId).ToList();

यह क्वेरी देगा

SELECT Id FROM Projects INNER JOIN (VALUES (1), (2), (3), (4), (5)) AS Data(Item) ON Projects.UserId = Data.Item

जबकि दूसरी तरफ कोई भी () हमेशा O (n) के माध्यम से पुनरावृति करता है।

उम्मीद है कि यह काम करेगा ...।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.