2011-11-21 10 views
11

मैंने हाल ही में छोटे संरचनाओं की एक श्रृंखला के लिए List<> बनाम [] पर कुछ मोटा प्रदर्शन किया है। सिस्टम.एरे को हाथों से जीतना प्रतीत होता था इसलिए मैं उसके साथ गया।क्या सिस्टम.एरेरे मूल्य प्रकारों पर मुक्केबाजी करते हैं या नहीं?

यह केवल मेरे लिए आया है कि सिस्टम.एरे में ऑब्जेक्ट प्रकार हैं, इसलिए निश्चित रूप से संरचनाओं के साथ भरने से मुक्केबाजी हो जाएगी?

हालांकि, the MSDN entry for System.Array कहता है:

.नेट फ्रेमवर्क संस्करण 2.0 में, सरणी वर्ग System.Collections.Generic.IList<T>, System.Collections.Generic.ICollection<T>, और System.Collections.Generic.IEnumerable<T> जेनेरिक इंटरफेस लागू करता है। कार्यान्वयन रन समय पर सरणी के लिए प्रदान किए जाते हैं, और इसलिए प्रलेखन निर्माण उपकरण के लिए दृश्यमान नहीं हैं। नतीजतन, जेनेरिक इंटरफेस ऐरे कक्षा के लिए घोषणा वाक्यविन्यास में प्रकट नहीं होते हैं, और सामान्य इंटरफ़ेस प्रकार (स्पष्ट इंटरफ़ेस कार्यान्वयन) के लिए सरणी कास्टिंग करके केवल इंटरफ़ेस सदस्यों के लिए कोई संदर्भ विषय नहीं हैं। ।

क्या इसका मतलब यह है कि मुक्केबाजी सभी के बाद नहीं होती है? (और मेरे प्रदर्शन परिणामों की व्याख्या करेगा)

+0

अपने प्रदर्शन परिणामों को समझाने के लिए शायद हमें उस कोड को देखना चाहिए जिसका उपयोग आपने प्रदर्शन को मापने के लिए किया था। – Snowbear

उत्तर

12

यदि आप इंडेक्सर नोटेशन का उपयोग करते हैं तो कोई सरणी का उपयोग नहीं करता है। उदा।

new int[2]; 
x=[1]=3; 

निम्नलिखित आईएल को संकलित करता है (ध्यान दें लाइन नंबर अप्रासंगिक हैं के रूप में वे किसी अन्य कोड का टुकड़ा से आते हैं)

IL_0011: ldc.i4.2 
IL_0012: newarr System.Int32 
IL_0017: stfld Int32[] x 
IL_001c: ldarg.0 
IL_001d: ldfld Int32[] x 
IL_0022: ldc.i4.1 
IL_0023: ldc.i4.3 
IL_0024: stelem.i4 

भाषाओं कि इंडेक्सर उपयोग नहीं कर सकते के लिए (और मैं वास्तव में नहीं है पता है कि वे मौजूद हैं या नहीं) Arrays के लिए संकलन समय पर 2 अन्य विधियां बनाई गई हैं।

यह इन सार्वजनिक तरीकों बनाता ::

public int Get(int index) 
public void Set(int index,int value) 

इन तरीकों में या तो बॉक्स नहीं है और सी # के माध्यम से सामान्य रूप से सुलभ नहीं हैं। (मुझसे मत पूछें कि वे सार्वजनिक तरीके क्यों हैं)। आप उन्हें आईएल या प्रतिनिधियों को बनाकर निष्पादित कर सकते हैं। वे धीमे हैं क्योंकि इन तरीकों का आह्वान करने के लिए आपको कॉलवर्ट करने के लिए मजबूर होना पड़ता है।

स्टीम। * और ldelem। * परिवार का उपयोग दृढ़ता से टाइप किए गए सरणी प्रकार को संग्रहीत करने के लिए किया जाता है। जेनिक्स का उपयोग करते समय आमतौर पर T[] का उपयोग करते समय निम्न उपसर्ग constrained या readonly संलग्न होते हैं। stelem.* प्रकार आमतौर पर प्रकार की जांच नहीं करते हैं। जैसे stelem.i4 का उपयोग stelem.any Int32 का उपयोग करने से तेज़ है जब तक कि आप इसे readonly से उपसर्ग न करें क्योंकि अन्यथा यह एक प्रकार की जांच को मजबूर करता है।

अब टाइपशेक पूरी तरह से मूल्यवान ऐरे पर बेकार है, वे नहीं हैं!

क्योंकि रनटाइम शून्य से शुरू होने वाली एक आयामी सरणी उत्पन्न करता है (या तो SZ_array या वेक्टर प्रकार कहा जाता है) प्रकार वे मूल रूप से ज्ञात होते हैं।

उनके लिए इल सेशन कोड के एक परिवार हैं: newarr, stelem.*, ldelem.*, ldlen आदि

List<T> प्रकार बीसीएल के माइक्रोसॉफ्ट कार्यान्वयन में अपनी समर्थन स्टोर के लिए एक T[] उपयोग करता है। List<T> बॉक्स नहीं है। सूची या सरणी का उपयोग करने के बावजूद आप किसी सरणी में चीजें संग्रहीत कर रहे हैं।

+1

यहां एरे के ढेर/ढेर आवंटन और उनके निहित मूल्यों के बारे में एक अन्य उत्तर के लिए एक पूरक लिंक है: http://stackoverflow.com/questions/1113819/arrays-heap-and-stack-and-value-types/1114152#1114152 – BoltClock

+1

चूंकि Arrays संदर्भ प्रकार हैं, इसलिए अनबॉक्स किए गए int को प्रबंधित ढेर में भी संग्रहीत किया जाता है - इसके बारे में बॉक्स के लिए कुछ भी नहीं है। – Alex

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