2010-07-05 4 views
5

इस कोड पर विचार करें समझना:विस्तार ElementAt (इंडेक्स)

int size = 100 * 1000 * 1000; 
var emu = Enumerable.Range(0, size); 
var arr = Enumerable.Range(0, size).ToArray(); 

जब मैं emu.ElementAt फोन (आकार -10) और arr.ElementAt (आकार -10) और समय आगमन तेज हो गया है को मापने (IENumerable 0.5 9s की तुलना में सरणी 0.0002 है)।

मैं यह समझ के रूप में, विस्तार विधि ElementAt() हस्ताक्षर

public static TSource ElementAt<TSource>(this IEnumerable<TSource> source, int index) 

और 'स्रोत' एक IEnumerable है के बाद से तर्क किए गए समान होगा - मैं क्या देखते हैं जहां सरणी करने का विरोध किया सीधे पहुंचा जा सकता है।

कोई यह समझाने कृपया सकते हैं :)

उत्तर

5

यह निष्पादन-समय पर प्रदर्शन किया गया एक अनुकूलन है। हालांकि कॉल ओवरलोड नहीं किया गया है, यह जांचने में सक्षम है (is या as का उपयोग करके) क्या स्रोत वास्तव में IList<T> है। यदि ऐसा है, तो यह सीधे सही तत्व पर जाने में सक्षम है। उल्लेखनीय Count() जो ICollection<T> के लिए अनुकूलित और है (.NET 4) के रूप में nongeneric ICollection इंटरफ़ेस -

विभिन्न अन्य कॉल यह करते हैं।

विस्तार विधियों के डाउनसाइड्स में से एक यह है कि इन सभी अनुकूलन को कार्यान्वयन द्वारा ही किया जाना चाहिए - प्रकार एक्सटेंशन विधियों को अनुकूलित करने के लिए "ऑप्ट इन" करने के लिए कुछ भी ओवरराइड नहीं कर सकते हैं। इसका मतलब है कि ऑप्टिमाइज़ेशन को सभी मूल कार्यान्वयनकर्ताओं द्वारा जाना जाना चाहिए :(

+0

आप अपने कस्टम संग्रह प्रकार को 'IList ' लागू करके ऑप्टिमाइज़ेशन में कुछ हद तक अप्रत्यक्ष रूप से ऑप्ट-इन कर सकते हैं, लेकिन इसे स्पष्ट रूप से कार्यान्वित करें और/या केवल अपने संग्रह को 'IENumerable ' के रूप में सार्वजनिक रूप से बेनकाब करें। यह आदर्श नहीं है, लेकिन मूल रूप से ये ऑप्टिमाइज़ेशन 'हुक' हैं। यदि आप चाहते थे, तो आप प्रत्येक कस्टम एक्सटेंशन विधि के लिए एक कस्टम इंटरफ़ेस प्रदान कर सकते हैं जो क्लास लेखक को एक्सटेंशन विधि व्यवहार को ओवरराइड करने की अनुमति देता है, हालांकि यह थोड़ा सा हो सकता है। 'widgetExtensions.ToggleWidget (यह विजेट विजेट) 'और' WidgetExtensions.IToggleWidget '। –

12

आइटम के माध्यम से एक IEnumerable<T> इच्छा पाश पर ElementAt कॉलिंग जब तक यह वांछित सूचकांक तक पहुँचता है। (एक हे (एन) आपरेशन)

एक IList<T> (जैसे एक सरणी के रूप में) पर ElementAt कॉलिंग IList<T> के इंडेक्सर का उपयोग तुरंत वांछित सूचकांक प्राप्त करने के लिए होगा। (एक ओ (1) ऑपरेशन)

+0

अरह, तो आप मुझे बता रहे हैं कि एलीमेंट्स एरीज़, लिस्ट्स, व्हाट्नॉट .. ?? – Moberg

+1

के लिए ओवरलोड किया गया है। यह एक प्रकार का कास्ट नहीं करता है। – SLaks

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