गणना गुण बनाम गणना () विधि?


85

एक संग्रह के साथ काम करना मेरे पास वस्तुओं की गिनती प्राप्त करने के दो तरीके हैं; Count(संपत्ति) और Count()(विधि)। क्या किसी को पता है कि प्रमुख अंतर क्या हैं?

मैं गलत हो सकता हूं, लेकिन मैं हमेशा Countकिसी भी सशर्त बयान में संपत्ति का उपयोग करता हूं, क्योंकि मैं मान रहा हूं कि Count()विधि संग्रह के खिलाफ कुछ प्रकार की क्वेरी करती है, जहां Countमुझे पहले से ही 'मिलने' से पहले सौंपा गया है। ' लेकिन यह एक अनुमान है - मुझे नहीं पता कि अगर मैं गलत हूं तो प्रदर्शन प्रभावित होगा।

संपादित करें: जिज्ञासा से बाहर, Count()एक अपवाद फेंक देंगे अगर संग्रह शून्य है? क्योंकि मुझे पूरा यकीन है कि Countप्रॉपर्टी केवल 0 ही देती है।


7
दोनों अशक्त संग्रह के लिए एक अपवाद फेंक देंगे, क्योंकि दोनों .ऑपरेटर को कुछ अशक्त करने की कोशिश कर रहे हैं ।
एरोनल्स

जवाबों:


109

Count()विस्तार विधि के लिए स्रोत को विघटित करने से पता चलता है कि यह परीक्षण करता है कि क्या वस्तु एक ICollection(सामान्य या अन्यथा) है और यदि ऐसा है तो अंतर्निहित Countसंपत्ति लौटाता है :

इसलिए, यदि आपका कोड Countकॉल करने के बजाय पहुंचता है Count(), तो आप प्रकार की जाँच को बायपास कर सकते हैं - एक सैद्धांतिक प्रदर्शन लाभ लेकिन मुझे संदेह है कि यह ध्यान देने योग्य होगा!

// System.Linq.Enumerable
public static int Count<TSource>(this IEnumerable<TSource> source)
{
    checked
    {
        if (source == null)
        {
            throw Error.ArgumentNull("source");
        }
        ICollection<TSource> collection = source as ICollection<TSource>;
        if (collection != null)
        {
            return collection.Count;
        }
        ICollection collection2 = source as ICollection;
        if (collection2 != null)
        {
            return collection2.Count;
        }
        int num = 0;
        using (IEnumerator<TSource> enumerator = source.GetEnumerator())
        {
            while (enumerator.MoveNext())
            {
                num++;
            }
        }
        return num;
    }
}

10
यह बहुत मददगार, रिवर्स इंजीनियर के लिए पहल करने के लिए +1।
बहुपद

7
हालाँकि, ध्यान रखें कि 3.5 Count()में गैर-जेनेरिक ICollectionइंटरफ़ेस की जाँच नहीं होती है। यह केवल .NET 4. में जोड़ा गया था ICollection<T>। जेनेरिक इंटरफ़ेस के लिए 3.5 और 4 दोनों चेक ।
१op:

2
किसी तत्व के साथ अनुक्रम पर कॉलिंग गणना एक अपवाद को फेंक देगी। लेकिन गिनती () ठीक काम करेगी।
अमीश

33

प्रदर्शन केवल एक या दूसरे को चुनने का एक कारण है। चुनने का .Count()मतलब है कि आपका कोड अधिक सामान्य होगा। मेरे पास ऐसे अवसर हैं जहां मैंने कुछ कोड को फिर से तैयार किया है जो अब एक संग्रह का उत्पादन नहीं करता है, बल्कि एक IEnumerable की तरह कुछ अधिक सामान्य है, लेकिन इसके परिणामस्वरूप अन्य कोड टूट गया क्योंकि यह निर्भर था .Countऔर मुझे इसे बदलना पड़ा .Count()। अगर मैंने .Count()हर जगह उपयोग करने के लिए एक बिंदु बनाया , तो कोड संभवतः अधिक पुन: प्रयोज्य और बनाए रखने योग्य होगा। आमतौर पर अधिक सामान्य इंटरफेस का उपयोग करने का विकल्प चुनने पर यदि आप इससे दूर हो सकते हैं तो यह आपकी सर्वश्रेष्ठ शर्त है। अधिक सामान्य द्वारा, मेरा मतलब है कि सरल इंटरफ़ेस जो कि अधिक प्रकारों द्वारा कार्यान्वित किया जाता है, और इस प्रकार आप कोड के बीच अधिक अनुकूलता को शुद्ध करते हैं।

मैं .Count()बेहतर नहीं कह रहा हूँ, मैं बस कह रहा हूँ कि अन्य विचार हैं जो आपके द्वारा लिखे गए कोड की पुन: प्रयोज्यता के साथ अधिक व्यवहार करते हैं।


2
चर्चा के लिए +1 मूल्यवान जोड़। कुछ कोड मैं बनाए रख रहा हूं क्योंकि संपत्ति। क्योंकि HtmlAgilityPack के संस्करण का नवीनीकरण नहीं हुआ।
दान सोलोवे

1
वह दोधारी तलवार हो सकती है। क्या होगा अगर किसी दिन कोई IEnumerable को संशोधित करने के लिए एक सच्चे जनरेटर होने की कोशिश करता है। कोडबेस को देखते हुए मुझे बहुत सारे स्थान दिखाई देते हैं जहाँ .Count () मानता है कि असंख्य को कई बार प्रसारित किया जा सकता है
bashrc

@bashrc सच। मुझे लगता है कि अगर हम डेवलपर के कोड को बनाम फ्रेमवर्क कोड को बदलने पर विचार कर रहे हैं, तो यह अधिक संभावना है कि डेवलपर कोड बदल जाएगा। अगर फ्रेमवर्क में इस तरह का बदलाव किया गया था, तो यह बहुत सी चीजों को तोड़ देगा। परंपरागत रूप से वे इन मामलों में नए संग्रह / इंटरफेस पेश करते हैं ताकि डेवलपर वांछित के रूप में पलायन कर सके।
एरोनल्स

20

.Count()विधि सकता है स्मार्ट पर्याप्त हो, या प्रश्न में प्रकार के बारे में पता है, और यदि हां, तो यह हो सकता है अंतर्निहित का उपयोग .Countसंपत्ति।

तो फिर, यह नहीं हो सकता है।

मैं कहूंगा कि यह मान लेना सुरक्षित है कि अगर कलेक्शन में .Countही संपत्ति है, तो प्रदर्शन के लिए आपकी सबसे अच्छी शर्त होगी।

यदि .Count()विधि संग्रह के बारे में नहीं जानती है, तो यह उस पर गणना करेगा, जो एक ओ (एन) ऑपरेशन होगा।


3
Countसंपत्ति का उपयोग करना बेहतर हो सकता है, लेकिन Count()उपयोग करने की विधि ICollection<T>.Countयहाँ थोड़े प्रलेखित है: msdn.microsoft.com/en-us/library/bb338038(v=vs.110).aspx
nawfal 12

मैं नहीं जानता कि आप लगभग सब कुछ कैसे जानते हैं।
एसएनआर

5

Count()विधि एक विस्तार विधि है जो प्रत्येक तत्व को पुनरावृत्त करती है IEnumerable<>और रिटर्न करती है कि कितने तत्व हैं। यदि IEnumerableवास्तव में इसका उदाहरण है List<>, तो यह Countसभी तत्वों को पुनरावृत्त करने के बजाय संपत्ति को वापस करने के लिए अनुकूलित है ।


यहां तक ​​कि जब मेरे पास एक सूची <> है, तो मैं अपने कोड को अधिक सामान्य रखने के लिए गणना () विधि का उपयोग करता हूं। इसका अच्छा तब है जब मैं अपनी कक्षाओं को IEnumerable <> का उपयोग करने के लिए मना कर रहा हूं, जहां विशिष्ट संग्रह कार्यान्वयन की कोई आवश्यकता नहीं है।
एंटोनियो आर.वी.

3

Count()LINQ से एक्सटेंशन विधि के रूप में है - s, वास्तविक .NET संग्रह वस्तुओं Countपर एक संपत्ति Listहै।

जैसे, Count()यह लगभग हमेशा धीमा होगा, क्योंकि यह संग्रह / क्वेरी योग्य वस्तु को फिर से जोड़ देगा। सूची, कतार, स्टैक आदि पर, का उपयोग करें Count। या एक सरणी के लिए - Length


3

लघु संस्करण: यदि आपके पास Countसंपत्ति के बीच विकल्प है और एक Count()विधि हमेशा संपत्ति का चयन करती है।

अंतर मुख्य रूप से ऑपरेशन की दक्षता के आसपास है। सभी बीसीएल संग्रह जो एक Countसंपत्ति को उजागर करते हैं वे एक ओ (1) फैशन में करते हैं। Count()विधि हालांकि कर सकते हैं, और अक्सर होगा, लागत हे (एन)। कुछ कार्यान्वयन के लिए O (1) पर जाने के लिए प्रयास करने और इसे प्राप्त करने के लिए कुछ जांचें हैं, लेकिन इसकी कोई गारंटी नहीं है।


मुझे लगता है कि यह उत्तर गिनती संपत्ति का उपयोग करने के लिए अधिक उचित है
एटी

3

यदि कोई संपत्ति है Countया नहीं Lengthहै, तो आपको हमेशा उस Count()विधि को पसंद करना चाहिए , जो आम तौर पर तत्वों की संख्या की गणना करने के लिए पूरे संग्रह को पुनरावृत्त करता है। अपवाद तब होगा जब Count()विधि LINQ से SQL या LINQ से एंटिटीस स्रोत तक होती है, उदाहरण के लिए, इस स्थिति में यह डेटा स्रोत के विरुद्ध एक गणना क्वेरी निष्पादित करेगा। फिर भी, अगर कोई Countसंपत्ति है, तो आप इसे पसंद करना चाहेंगे, क्योंकि इसकी संभावना कम काम करने की है।


3

Count()विधि LINQ विधि है कि किसी भी पर काम करता है IEnumerable<>। आप Count()गणना को खोजने के लिए पूरे संग्रह पर पद्धति को पुन: व्यवस्थित करने की अपेक्षा करेंगे , लेकिन मेरा मानना ​​है कि LINQ कोड वास्तव में कुछ अनुकूलन है ताकि यह पता लगाया जा सके कि क्या गणना गुण मौजूद है और यदि ऐसा है तो उपयोग करें।

इसलिए वे दोनों लगभग समान चीजें करना चाहिए। काउंट प्रॉपर्टी शायद थोड़ी बेहतर है क्योंकि वहां एक प्रकार की जांच की आवश्यकता नहीं है।

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