2010-07-16 11 views
9

लिंकक पर Count() विधि का उपयोग करके गणना-संपत्ति के परिणाम को वापस करने जैसी कई चालाक चीजें करता है। क्या कोई अच्छा स्रोत है जो इस अनुकूलन का अवलोकन देता है?क्या कोई अच्छा स्रोत है जो linq अनुकूलन का अवलोकन देता है?

यह क्योंकि जैसा कि इससे पहले कि मैं ऊपर पता था कि बहुत ही दिलचस्प हो सकता है, मैं Count() इस्तेमाल किया और इस प्रकार अक्सर केवल एक IEnumerable<T> की तुलना में एक List<T> लौटे क्योंकि मैं जानता था कि फोन करने वाले अक्सर सूची के कहने गिनती की जरूरत की आवश्यकता होगी कभी नहीं।

लेकिन ध्यान में रखते हुए कि गणना() वास्तव में IEnumerable<T> में निहित उदाहरणों की गणना नहीं करती है, लेकिन लौटाई गई सूची से गणना-संपत्ति का परिणाम लौटाती है और इसलिए प्रदर्शन को खोने से मुझे अपने कई लौटने वाले प्रकारों को बदलने का अवसर नहीं मिला सूची से IEnumerable<T> पर।

+0

"लिंकक बहुत सारे अनुकूलन करता है जैसे कि गलती() विधि का उपयोग करके गिनती() विधि का उपयोग करके गणना-संपत्ति का परिणाम लौटाता है ??? –

+0

@ मिच: संभावित रूप से एक LINQ क्वेरी सभी अंतर्निहित डेटा पुनर्प्राप्त नहीं करती है जब एक सरल 'गणना()' कॉल करेगा। –

+0

मैंने कुछ मिनट पहले सीखा था कि एक सूची में AsEnumerable को कॉल करने से कोई नया उदाहरण नहीं बनता है, लेकिन केवल इंस्टेंस ही लौटाता है। लेकिन शायद शब्द अनुकूलन सही नहीं है। ए ने प्रश्न-पाठ को और अधिक सटीक रूप से दिखाने के लिए बदल दिया है जो मेरा मतलब है। – HCL

उत्तर

6

वर्तमान अनुकूलन है कि मैं के बारे में पता कर रहा हूँ:

  • Count अनुक्रम ICollection<T> लागू करता है और एक विधेय नहीं किया जाता है, तो Count संपत्ति का उपयोग करता है। यदि अनुक्रम को लागू करता है IList<T> (.NET 4 Count में भी गैर सामान्य ICollection लिए अनुकूलित है।) सूचकांक द्वारा

  • ElementAt/ElementAtOrDefault पहुँच। सूचकांक द्वारा

  • Last/LastOrDefault पहुँच यदि अनुक्रम IList<T> लागू करता है और एक विधेय नहीं किया जाता है।

  • ToArray/ToList स्मृति को आबंटित करने और अधिक कुशलता से करता है, तो अनुक्रम को लागू करता है ICollection<T>Count संपत्ति का उपयोग करें। (लेकिन उनमें से कोई भी ICollection के लिए अनुकूलित।)

अनुकूलन है कि वहाँ हो सकता है लेकिन नहीं कर रहे हैं:

  • Last/LastOrDefault मामले में जहां एक विधेय प्रयोग किया जाता है में अनुकूलन नहीं है। ऐसा कोई कारण नहीं है कि वे IList<T> के लिए ऑप्टिमाइज़ नहीं कर सके, सूची के माध्यम से पीछे की ओर इशारा करते हुए और इंडेक्स द्वारा प्रत्येक तत्व तक पहुंचने के लिए।

  • SequenceEqualICollection<T> और ICollection के लिए अनुकूलित कर सकता है, यह निर्धारित करने के Count संपत्ति का उपयोग कर यदि सूचियों समान अवधि वाले और जल्दी बाहर तोड़ने अगर वे नहीं कर रहे हैं।

  • SkipIList<T> के लिए अनुकूलित कर सकता है, सूचकांक द्वारा तत्वों तक पहुँचने और सूचकांक n पर सीधे शुरू करने बल्कि पुनरावृत्ति और पहली n तत्वों को त्यागकर से।

  • ToArray/ToList भी ICollection के लिए अनुकूलित कर सकता है, और अधिक कुशलता से स्मृति को आबंटित करने Count संपत्ति का उपयोग कर।

  • ToDictionaryICollection<T> और ICollection के लिए अनुकूलित कर सकता है, अधिक कुशलतापूर्वक स्मृति को आबंटित करने Count संपत्ति का उपयोग कर।

+1

मैंने [Nito.Linq] (http://nitolinq.codeplex.com/) लाइब्रेरी के विकास के दौरान परावर्तक का उपयोग करके गहराई से इसका शोध किया है। ल्यूक का जवाब बहुत पूरा है। मैं केवल उस स्मृति को पुनर्स्थापित करने के लिए 'ToList' और' ToArray' 'गणना' का उपयोग करता हूं। साथ ही, 'खाली' और 'अनुक्रम Equal' को संभावित रूप से' गणना 'का उपयोग करके अनुकूलित किया जा सकता है। अंत में, 'रिवर्स' को अनुकूलित करने की भी संभावना है, लेकिन यह विवादास्पद है क्योंकि यह अर्थशास्त्र [बफरिंग से स्ट्रीमिंग] में बदलता है (http://msmvps.com/blogs/jon_skeet/archive/2010/03/25/just-how -lazy-हैं-you.aspx)। –

+0

@ स्टीफन: मैं 'सीक्वेंस एक्वाल' के संभावित अनुकूलन के बारे में सब भूल गया, भले ही मेरे पास अपने स्वयं के LINQ सहायक पुस्तकालय में एक अनुकूलित संस्करण है। मैं इसे सूची में जोड़ दूंगा। क्या आप विस्तारित कर सकते हैं कि 'खाली' को कैसे अनुकूलित किया जा सकता है? जहां तक ​​मुझे पता है, यह सिर्फ एक सिंगलटन खाली अनुक्रम देता है। – LukeH

+0

आप सही हैं; मैंने अपने नोट्स को दोबारा जांच लिया और गलती से मेरी टिप्पणी में 'खाली' लगाया गया। माफ़ कीजिये... –

13

.NET Reflector आज़माएं। क्लास लाइब्रेरी ब्राउज़ करने के लिए यह एक शानदार टूल है, इसमें एक शक्तिशाली डिकंपेलर है जो आपको स्रोत कोड को जितना लिखा गया था उतना ही देखते हैं।

उदा। Count() विस्तार विधि बंद मौका है कि स्रोत संग्रह इंटरफ़ेस आप वास्तविक acount पाने के लिए गिनती करना होगा लागू नहीं है पर इस

if (source == null) 
{ 
    throw Error.ArgumentNull("source"); 
} 
ICollection<TSource> is2 = source as ICollection<TSource>; 
if (is2 != null) 
{ 
    return is2.Count; 
} 
ICollection is3 = source as ICollection; 
if (is3 != null) 
{ 
    return is3.Count; 
} 
int num = 0; 
using (IEnumerator<TSource> enumerator = source.GetEnumerator()) 
{ 
    while (enumerator.MoveNext()) 
    { 
     num++; 
    } 
} 
return num; 

की तरह किया जाता है। इस तरह कोड ब्राउज़ करना सीखने का एक शानदार तरीका है।

संबंधित मुद्दे