क्या सूची उपलब्ध होने पर किसी सरणी का उपयोग करने का कोई कारण है? [बन्द है]


30

ऐसा लगता है जैसे List<T>C # सब कुछ कर सकता है जो एक ऐरे कर सकता है और बहुत कुछ कर सकता है, और यह एरे के रूप में मेमोरी और प्रदर्शन में भी उतना ही कुशल लगता है।

तो मैं एक सरणी का उपयोग क्यों करना चाहूंगा?

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


56
लागू करने के लिएList<T>
शाफ़्ट सनकी

43
is also just as efficient in memory and performance as an array- उम। आपको वह धारणा कहां से मिली?
Oded

12
कई आयाम जैसे var test = new string[5,5];)
Knerd

7
आमतौर पर इस्तेमाल होने वाली बाइट [] सरणी भी है।
SBoss

11
C # के लिए, विशेष रूप से, एरिक लिपर्ट ने blogs.msdn.com/b/ericlippert/archive/2008/09/22/… में इस बारे में लिखा ।
Mephy

जवाबों:


26

यही कारण है कि जब मैं काम पर जाता हूं तो मैं ट्रक नहीं चलाता हूं। मैं ऐसी किसी चीज़ का उपयोग नहीं करता जिसका उपयोग मैं नहीं करूँगा।

सबसे पहले एक सरणी एक आदिम निर्माण है इसलिए एक सरणी सुनिश्चित करने के लिए एक सूची <> की तुलना में तेज़ और अधिक कुशल है, इसलिए आपका तर्क सत्य नहीं है। ऐरे भी हर जगह उपलब्ध है और डेवलपर्स द्वारा विभिन्न भाषाओं और प्लेटफार्मों का उपयोग करके जाना जाता है।

सबसे महत्वपूर्ण कारण मैं एक सूची के बजाय एक सरणी का उपयोग करता हूं <> इसका मतलब यह है कि डेटा की लंबाई निर्धारित है । यदि मैं उस डेटा संग्रह से कोई आइटम नहीं जोड़ूंगा या निकालूंगा, तो मैं यह सुनिश्चित करना चाहता हूं कि वह प्रकार प्रतिबिंबित हो।

एक और बात यह है कि आप एक नई डेटा संरचना को लागू कर रहे हैं और आपने इसके बारे में कुछ कागजात पढ़े हैं। अब विशिष्ट एल्गोरिदम को लागू करते समय, आप हमेशा किसी अन्य प्रकार के कार्यान्वयन पर भरोसा नहीं कर सकते हैं जो सामान्य उद्देश्य है। यह .NET से मोनो और यहां तक ​​कि फ्रेमवर्क के विभिन्न संस्करणों के बीच बदलता है।

और कभी-कभी कोड का एक टुकड़ा पोर्ट करना आसान होता है जो किसी फ्रेमवर्क पर निर्भर प्रकार के बजाय एक सरणी का उपयोग करता है।


4
किसी सूची की तुलना में एक सरणी "तेज़" कैसे होती है, यह देखते हुए कि List<T>एक सरणी का उपयोग करके लागू किया जाता है ? यदि आप पहले से गणना करते हैं (जो आपको जानना है, जब आप किसी सरणी का उपयोग कर रहे हैं) तत्व को जानते हैं, तो सूची को प्रारंभ करते समय आप उस ज्ञान का उपयोग कर सकते हैं।
थियोडोरोस चट्जीगानियाकिंस

1
@ TheodorosChatzigiannakis एक सरणी का उपयोग करते समय हम मेमोरी आवंटित करते हैं और बस असाइनमेंट करते हैं, सादे मालॉक (), ओवरहेड नहीं। जब आप सूची का उपयोग कर रहे हैं <> आप आइटम जोड़ेंगे "और आइटम जोड़ते समय सूची <> कुछ सीमा की जाँच करता है और सुनिश्चित करता है कि सुनिश्चित करें कि वर्तमान क्षमता पर्याप्त नहीं है, तो अन्य नए आवंटित सरणी के लिए सामग्री की नकल करेंगे। इसका मतलब है कि अगर आपको नई मेमोरी को गतिशील रूप से आवंटित करने की आवश्यकता नहीं है, तो सूची का प्रदर्शन सरणी के रूप में अच्छा नहीं है।
मर्ट अक्ककाया

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

3
@ TheodorosChatzigiannakis: Arrays सूचियों की तुलना में तेज़ हैं । जांच के लिए बस एक साधारण बेंचमार्क चलाएं।
मेहरदाद

1
@ TheodorosChatzigiannakis, हाँ, लेकिन अभी भी सीमा की जाँच है।
मर्ट अक्काया

18

आपको निश्चित रूप से परिवर्तनशील संरचनाओं के अपने संग्रह का प्रबंधन करने के लिए सरणियों की आवश्यकता है , और हम उन लोगों के बिना क्या करेंगे।

struct EvilMutableStruct { public double X; } // don't do this

EvilMutableStruct[] myArray = new EvilMutableStruct[1];
myArray[0] = new EvilMutableStruct()
myArray[0].X = 1; // works, this modifies the original struct

List<EvilMutableStruct> myList = new List<EvilMutableStruct>();
myList.Add(new EvilMutableStruct());
myList[0].X = 1; // does not work, the List will return a *copy* of the struct

(ध्यान दें कि कुछ ऐसे मामले भी हो सकते हैं, जहां उत्परिवर्तित संरचना का एक सरणी वांछनीय है, लेकिन आमतौर पर सरणियों के भीतर उत्परिवर्तनीय संरचनाओं का यह भिन्न व्यवहार बनाम अन्य संग्रह त्रुटियों का एक स्रोत है जिसे टाला जाना चाहिए)


अधिक गंभीरता से, आपको एक सरणी की आवश्यकता है यदि आप संदर्भ द्वारा एक तत्व पास करना चाहते हैं । अर्थात

Interlocked.Increment(ref myArray[i]);  // works
Interlocked.Increment(ref myList[i]);   // does not work, you can't pass a property by reference

यह लॉक-फ्री थ्रेडसेफ़ कोड के लिए उपयोगी हो सकता है।


आपको एक सरणी की आवश्यकता है यदि आप जल्दी और कुशलता से डिफ़ॉल्ट मूल्य के साथ अपने निश्चित आकार के संग्रह को शुरू करना चाहते हैं ।

double[] myArray = new double[1000]; // contains 1000 '0' values
                                     // without further initialisation

List<double> myList = new List<double>(1000) // internally contains 1000 '0' values, 
                                             // since List uses an array as backing storage, 
                                             // but you cannot access those
for (int i =0; i<1000; i++) myList.Add(0);   // slow and inelegant

(ध्यान दें कि सूची के लिए एक कंस्ट्रक्टर को लागू करना संभव होगा जो ऐसा करता है, यह सिर्फ इतना है कि c # इस सुविधा की पेशकश नहीं करता है)


यदि आप कुशलतापूर्वक संग्रह के कुछ हिस्सों को कॉपी करना चाहते हैं, तो आपको एक सरणी की आवश्यकता है

Array.Copy(array1, index1, array2, index2, length) // can't get any faster than this

double[,] array2d = new double[10,100];
double[] arraySerialized = new double[10*100];
Array.Copy(array2d, 0, arraySerialized, 0, arraySerialized.Length);
// even works for different dimensions

(फिर से, यह कुछ ऐसा है जिसे सूची के लिए भी लागू किया जा सकता है, लेकिन यह सुविधा c # में मौजूद नहीं है)


यदि किसी प्रकार को डक्ट टेप (जैसे एक बिंदु के निर्देशांक) के साथ मिलकर संबंधित-लेकिन-स्वतंत्र चर के समूह का प्रतिनिधित्व करना है, तो एक उजागर-क्षेत्र संरचना सबसे अच्छा प्रतिनिधित्व है। यदि एक चर को ऐसे समूहों का एक समूह माना जाता है, तो संरचना संरचना का एक सरणी सबसे अच्छा प्रतिनिधित्व है। जिन स्थानों पर किसी वस्तु को चाहा जाता है, उनमें से एक का उपयोग नहीं करना चाहिए, लेकिन इसका मतलब यह नहीं है कि वस्तुओं का उपयोग करना चाहिए या उन चीजों का उपयोग करना चाहिए जो उन जगहों पर वस्तुओं का होना चाहते हैं जहां एक चर का एक गुच्छा डक्ट टेप के साथ एक साथ अटक जाता है।
सुपरकैट

कुछ परिस्थितियाँ ऐसी होती हैं जहाँ आप एक परिवर्तनशील संरचना चाहते हैं, जैसे कि जब आपको अंतिम प्रदर्शन की आवश्यकता होती है और ढेर आवंटन और संदर्भों को वहन नहीं कर सकते हैं, और उस स्थिति में एक संरचना का एक सरणी आपकी सबसे अच्छी शर्त होती है। यहां अच्छा निबंध । लेकिन मैं असहमत हूं कि एक वर्ग को "एक साथ अटके हुए चर का एक गुच्छा" का प्रतिनिधित्व नहीं करना चाहिए। वैचारिक रूप से संरचनाएं और कक्षाएं ज्यादातर समान हैं, अंतर मुख्य रूप से कार्यान्वयन विवरण के कारण हैं।
ह्यूगो रून

यदि कोई स्वतंत्र चर के स्वतंत्र समूहों के संग्रह के रूप में उत्परिवर्तनीय-वस्तु संदर्भों के एक संग्रह का उपयोग करना चाहता है, तो किसी को एक अपरिवर्तनीय को स्थापित करना और बनाए रखना होगा जो प्रत्येक तत्व एक ऐसी वस्तु की पहचान करता है जिसके ब्रह्मांड में कहीं भी कोई अन्य गैर-पंचांग संदर्भ मौजूद नहीं है। यह निश्चित रूप से किया जा सकता है (और अक्सर होता है), लेकिन उस आक्रमणकारी को बनाए रखने में प्रोग्रामर की सहायता करने के लिए भाषा या रूपरेखा में कुछ भी नहीं है। इसके विपरीत, चार आवृत्ति क्षेत्रों के साथ संरचना प्रकार की लंबाई -100 सरणी स्वचालित रूप से और स्थायी रूप से 400 स्वतंत्र चर को एन्क्रिप्ट कर सकती है।
सुपरकैट

मुझे लगता है कि ये टिप्पणियां इस मुद्दे पर आगे चर्चा करने के लिए गलत जगह हैं, और जैसा कि आपने अपना जवाब जोड़ा है , यह देखते हुए यहां इस जानकारी की नकल करने की आवश्यकता नहीं लगती है। कहने के लिए पर्याप्त, सरणियों का उपयोग उत्परिवर्ती संरचनाओं के प्रबंधन के लिए किया जा सकता है। क्या और कब उन डेटा के कार्यान्वयन व्यवहार का उपयोग करने के लिए कुछ डेटा बाधाओं को लागू करने के लिए वास्तव में मेरे उत्तर के दायरे से परे चला जाता है।
ह्यूगो रून

15

तो मैं एक सरणी का उपयोग क्यों करना चाहूंगा?

शायद ही कभी , आपके पास एक परिदृश्य होगा जहां आप जानते हैं कि आपको निश्चित संख्या में तत्वों की आवश्यकता है। एक डिजाइन के नजरिए से, इससे बचना चाहिए। यदि आपको 3 चीजों की आवश्यकता है, तो व्यवसाय की प्रकृति का मतलब है कि आपको अगली रिलीज़ में अक्सर 4 की आवश्यकता होगी।

फिर भी, जब यह दुर्लभ परिदृश्य वास्तव में होता है, तो उस निश्चित आकार को लागू करने के लिए एक सरणी का उपयोग करना उपयोगी होता है। यह अन्य प्रोग्रामरों को एक संकेत प्रदान करता है कि यह एक निश्चित आकार है, और दुरुपयोग को रोकने में मदद करता है जहां कोई व्यक्ति किसी तत्व को जोड़ता है या हटाता है - कोड में कहीं और अपेक्षाओं को तोड़ता है।


23
एक बार कोड लिखने पर सरणियों का आकार पत्थर में सेट नहीं होता है। यह, और अक्सर, एक रन-टाइम चर है। यह सरणी बनाए जाने के बाद बस कभी नहीं बदलता है ।

11
तत्वों की निश्चित संख्या से निपटना असामान्य नहीं है। यदि आप 3 डी अंकों के साथ काम कर रहे हैं, तो आप भविष्य में किसी भी बिंदु पर 5D अंक के साथ काम नहीं करेंगे। सरणियों के साथ बड़ा मुद्दा यह है कि वे परिवर्तनशील हैं और उनके तत्वों से जुड़े सुविधाजनक लेबल नहीं हैं।
डोभाल

3
@JDDvorak सूचियाँ सिकुड़ या बढ़ सकती हैं और इस प्रकार किसी भी संदर्भ में तत्वों की निश्चित संख्या से कोई मतलब नहीं होता है।
डोभाल

9
शायद ही कभी? हर कोई सुपर-कॉम्प्लेक्स अल्ट्रा-कॉन्फिगरेबल एंटरप्राइज मोनस्ट्रोसिटी पर काम नहीं करता है।
whatsisname

3
तत्वों की एक निश्चित संख्या होना बहुत आम है। बस यह सुनिश्चित करें कि लंबाई एक स्थिर द्वारा परिभाषित की गई है, इसलिए जब अगली रिलीज में तत्वों की संख्या 3 से 4 हो जाती है, तो आप बस निरंतर बदलते हैं और इस पर निर्भर होने वाली सभी चीजों को अनुकूलित किया जाता है।
हंस

9

आपके प्रश्न का उत्तर वास्तव में पहले ही दिया जा चुका है

और यह भी एक सरणी के रूप में स्मृति और प्रदर्शन में कुशल लगता है।

यह नहीं है। मेरे द्वारा जुड़े प्रश्न से:

List/foreach:  3054ms (589725196)
Array/foreach: 1860ms (589725196)

Arrays कुछ महत्वपूर्ण मामलों में दो गुना तेज है। मुझे लगता है कि स्मृति उपयोग गैर-तुच्छ रूप से भी भिन्न है।

चूंकि आपके प्रश्न का मुख्य आधार इस प्रकार पराजित हुआ है, इसलिए मैं आपके प्रश्न का उत्तर दे रहा हूं। इसके अतिरिक्त, कभी-कभी एरे आपको Win32 API, या आपके GPU के shader, या कुछ अन्य गैर-DNetNet लाइब्रेरी द्वारा मजबूर किया जाता है।

डॉटनेट के भीतर भी, कुछ विधियाँ उपभोग करती हैं और / या वापसी सरणियाँ (जैसे String.Split)। जिसका अर्थ है कि या तो आपको अब कॉलिंग की लागत ToListऔर ToArrayहर समय खाना चाहिए , या आपको अनुरूप होना चाहिए और सरणी का उपयोग करना चाहिए, संभवतः यह आपके कोड के गरीब डाउनस्ट्रीम उपयोगकर्ताओं को प्रचारित करके चक्र को जारी रखेगा ।

इस विषय पर स्टैक ओवरफ्लो पर अधिक प्रश्न और उत्तर:


दिलचस्प बात यह है बाहर अगर आप पुराने जमाने अनुक्रमित छोरों (का उपयोग करें कि है कि इसका जवाब अंक के लिए के बजाय foreach ) प्रदर्शन अंतर कम है।
user949300

3

अन्य उत्तरों में सूचीबद्ध कारणों के अलावा, सरणी शाब्दिक घोषित करने के लिए कम वर्ण लेता है:

var array = new [] { "A", "B", "C" };
var list = new List<string>() { "A", "B", "C" };

इसके बजाय ऐरे का उपयोग करना Listकोड को थोड़ा छोटा बनाता है और ऐसे मामलों में जब आप (1) आपको किसी भी IEnumerable<T>शाब्दिक, या (2) को पास करने की आवश्यकता होती है , जहां कोई अन्य कार्यक्षमता Listनहीं होती है और आपको कुछ सूची का उपयोग करने की आवश्यकता होती है शाब्दिक।

मैंने यह कभी-कभी यूनिट परीक्षणों में किया है।


1
हाँ बस जोड़ने के लिए। यह भी आप का काम करता है एक IList <T> पास करने की जरूरत है
Esben Skov Pedersen

+1, अक्सर मेरे पास उसी प्रकार की कुछ वस्तुओं के लिए कुछ ऑपरेशन होता है जो संग्रह में नहीं होते हैं। यह लिखना आसान है, foreach( var x in new []{ a, b, c ) ) DoStuff( x )या स्पष्ट है या new []{ a, b, c ).Select( ... )आदि
stijn

3

यह एक OO के नजरिए से कड़ाई से है।

हालांकि मैं सिर्फ एक सरणी को पास करने के लिए एक कारण के बारे में नहीं सोच सकता, मैं निश्चित रूप से ऐसी परिस्थितियां देख सकता हूं जहां कक्षा के लिए आंतरिक रूप से एक सरणी प्रतिनिधित्व संभवतः सबसे अच्छा विकल्प है।

हालांकि, ऐसे अन्य विकल्प हैं जो समान विशेषताओं को देते हैं, कोई भी प्रसंस्करण क्रमपरिवर्तन से संबंधित समस्याओं के लिए एक सरणी के रूप में सहज नहीं लगता है, छोरों के लिए नेस्टेड, मैट्रिक्स प्रतिनिधित्व, बिटमैप और डेटा इंटरलेइंग एल्गोरिदम।

ऐसे कई वैज्ञानिक क्षेत्र हैं जो मैट्रिक्स गणित पर बड़े पैमाने पर निर्भर हैं। (उदाहरण के लिए इमेज प्रोसेसिंग, डेटा एरर करेक्शन, डिजिटल सिग्नल प्रोसेसिंग, लागू गणित की एक समस्या)। उन क्षेत्रों में अधिकांश एल्गोरिदम बहुआयामी सरणियों / मैट्रिक्स का उपयोग करने के संदर्भ में लिखे गए हैं। इसलिए एल्गोरिदम को लागू करना अधिक स्वाभाविक होगा क्योंकि उन्हें परिभाषित करने के बजाय उन्हें अधिक "सॉफ़्टवेयर" के अनुकूल बनाया जाएगा, जो कि एल्गोरिदम पर आधारित कागजों से सीधे टाई-इन को खोने की कीमत पर अनुकूल हैं।

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


3

यह वास्तव में अन्य भाषाओं के लिए जाता है जिनकी सूची (जैसे जावा या विज़ुअल बेसिक) है। ऐसे मामले हैं जहां आपको एक सरणी का उपयोग करने की आवश्यकता होती है क्योंकि एक विधि सूची के बजाय एक सरणी देता है।

एक वास्तविक कार्यक्रम में, मुझे नहीं लगता कि एक सरणी का उपयोग अक्सर किया जाएगा, लेकिन कभी-कभी आप जानते हैं कि डेटा एक निश्चित आकार होगा और आपको सरणी के उपयोग से प्राप्त होने वाले छोटे प्रदर्शन लाभ पसंद हैं। माइक्रो-ऑप्टिमाइज़ेशन एक वैध कारण होगा, जैसे किसी सूची को वापस करने की विधि, या बहुआयामी डेटास्ट्रक्चर की आवश्यकता।


1
कई भाषाओं में अलग-अलग सूची और सरणी संग्रह भी नहीं होते हैं। दूसरी ओर, list<T>जहां vector<T>काम करेगा का उपयोग C / C ++ में एक विनाशकारी बुरा विचार है।
रोबोट

1
"क्योंकि एक विधि एक सरणी देता है" - यह जावा का एक मिसफिट है, प्रोग्रामर को "Arrays.asList (x)" के साथ कोड को क्रैप करने के लिए मजबूर करता है। T [] कम से कम Iterable लागू करना चाहिए <T>
केविन cline

4
@StevenBurnap - यह निश्चित रूप से C में विनाशकारी रूप से खराब है, क्योंकि उस कोड को संकलित करने का कोई तरीका नहीं है।
पीट बेकर

@PeteBecker अभिव्यक्ति vector<T> x सी में मेरे लिए ठीक संकलित करती है । :-)
svick

क्षमा करें, मेरा मतलब था सी-रोल के बराबर list<T>। मूल रूप से, मैंने कई प्रदर्शन समस्याओं को देखा है जो डेवलपर्स द्वारा केवल डिफ़ॉल्ट रूप से सूचियों का उपयोग करने के कारण होती हैं जब एक सरणी एक बेहतर विकल्प था।
रोबोट

1

खैर, मुझे एक ऐसे खेल में सरणियों का उपयोग मिला जो मैं लिख रहा हूं। मैंने एक निश्चित संख्या में स्लॉट के साथ एक इन्वेंट्री सिस्टम बनाने के लिए इसका इस्तेमाल किया। इसके कई लाभ थे:

  1. मुझे ठीक से पता था कि गेम ऑब्जेक्ट को देखकर कितनी खुली इन्वेंट्री स्लॉट्स हैं और देखकर पता चलता है कि कौन से स्लॉट शून्य थे।
  2. मुझे पता था कि प्रत्येक आइटम किस सूचकांक में है।
  3. यह अभी भी एक "टाइप किया हुआ" एरे (आइटम [] इन्वेंटरी) था, इसलिए मैं टाइप "आइटम" की वस्तुओं को जोड़ / हटा सकता था।

मुझे लगा कि अगर मुझे कभी भी इन्वेंट्री के आकार को "बढ़ाने" की जरूरत है, तो मैं पुरानी वस्तुओं को नए सरणी में स्थानांतरित करके ऐसा कर सकता था, लेकिन चूंकि इन्वेंट्री स्क्रीन स्पेस द्वारा तय की गई थी और मुझे इसे गतिशील रूप से बड़ा करने की कोई आवश्यकता नहीं थी / छोटा, यह उस उद्देश्य के लिए अच्छी तरह से काम करता है जिसका मैं इसके लिए उपयोग कर रहा था।


1

यदि आप किसी सूची के सभी तत्वों को ट्रेस कर रहे हैं, तो नहीं, एक सरणी आवश्यक नहीं है, 'अगला' या मनमाना 'प्रतिस्थापन के बिना चयन' ठीक होगा।

लेकिन अगर आपके एल्गोरिथ्म को संग्रह में तत्वों तक यादृच्छिक पहुंच की आवश्यकता है, तो, हां, एक सरणी आवश्यक है।

यह कुछ हद तक "गोटो आवश्यक है?" के अनुरूप है। एक उचित आधुनिक भाषा में इसकी बिल्कुल भी आवश्यकता नहीं है। लेकिन अगर आप कुछ बिंदुओं पर, अमूर्तता को छील लेते हैं, तो यह सब वास्तव में आपके लिए उपलब्ध है, यानी इन अमूर्त को लागू करने का एकमात्र तरीका 'अनावश्यक' विशेषता है। (बेशक, सादृश्य परिपूर्ण नहीं है, मुझे नहीं लगता कि कोई भी कहता है कि सरणियाँ खराब प्रोग्रामिंग अभ्यास हैं; उन्हें समझना और उनके बारे में सोचना आसान है)।


सूची <T> भी यादृच्छिक पहुँच प्रदान करता है। ज़रूर, यह एक सरणी के साथ लागू किया गया है, लेकिन इससे आपको उपयोगकर्ता को परेशान करने की आवश्यकता नहीं है। तो सबसे अच्छा है, आपने सरणियों का उपयोग करने के लिए एक ही कारण की पेशकश की: लागू करने के लिए List<T>

@delnan मुझे लगता है कि अमूर्तता के संबंध में मेरी बात है। कभी-कभी किसी सरणी के संदर्भ में सोचना बेहतर होता है, न कि केवल दक्षता कारणों से। (निश्चित रूप से कभी-कभी यह एक लिंक की गई सूची के बारे में सोचना बेहतर होता है, और इससे बेहतर होता है कि एक सूची के बारे में सोचा जाए (लिंक की परवाह किए बिना या अन्यथा इसे कैसे लागू किया जाता है), और जिस तरह से बेहतर है सिर्फ एक संग्रह।
मिच

0

विरासत की अनुकूलता।

सभी व्यक्तिगत अनुभव बनाते हैं:

लीगेसी प्रोग्रामर - मेरे सहयोगी ने हर जगह सरणियों का उपयोग किया है, 30+ वर्षों के लिए किया है, सौभाग्य आपके नए भद्दे विचारों के साथ अपना मन बदल रहा है।

लिगेसी कोड - foo (एरे बार) [] सुनिश्चित करें कि आप एक सूची / वेक्टर / संग्रह टॉर्रे फंक्शन का उपयोग कर सकते हैं, लेकिन यदि आप किसी अतिरिक्त सुविधा का उपयोग नहीं कर रहे हैं, तो टाइप करने के लिए ऐरे का उपयोग करना आसान है, अक्सर टाइप स्विचिंग के बिना अधिक पठनीय।

लीगेसी बॉस - कई साल पहले प्रबंधन में जाने से पहले मेरा बॉस एक अच्छा प्रोग्रामर था और अब भी सोचता है कि वह अप टू डेट है, "एरे का उपयोग कर रहे थे" एक मीटिंग को समाप्त कर सकता है, यह समझाते हुए कि एक संग्रह में हर किसी के दोपहर के भोजन का खर्च हो सकता है।


3
सहकर्मी जो वक्र के 20 साल पीछे हैं और एक बॉस है जो जानना चाहता है कि आप किस प्रकार के डेटा का उपयोग कर रहे हैं ... मुझे यह साइट खुद को याद दिलाने के लिए पसंद है कि मेरी नौकरी कितनी खराब हो सकती है
जोएलफैन

1
लगभग 40% हम जो करते हैं वह एम्बेडेड डिज़ाइन होता है जहां केबी में चर्चाएं होती हैं, वह मुझे यह बताना पसंद करते हैं कि वे पुरानी नहीं हैं, अटकलें लगाई गई लोल
स्केथ

0

1) सूची का कोई बहुआयामी संस्करण नहीं है। यदि आपके डेटा में एक से अधिक आयाम हैं, तो सूचियों का उपयोग करना बहुत अक्षम होगा।

2) जब आप बड़ी संख्या में छोटे प्रकार के डेटा के साथ काम कर रहे हों (जैसे, एक नक्शा जहां आपके पास सभी प्रकार के इलाके के लिए एक बाइट है) कैशिंग के कारण काफी प्रदर्शन अंतर हो सकते हैं। सरणी संस्करण प्रति मेमोरी रीड की गई कई वस्तुओं को लोड करता है, सूची संस्करण केवल एक को लोड करता है। इसके अलावा, सरणी संस्करण सूची संस्करण के रूप में कैश में कई सेल के रूप में कई बार रखता है - यदि आप बार-बार डेटा संसाधित कर रहे हैं तो यह एक बड़ा अंतर बना सकता है यदि सरणी संस्करण कैश में फिट बैठता है लेकिन सूची संस्करण नहीं है।

एक चरम मामले के लिए, Minecraft पर विचार करें। (हाँ, यह C # में नहीं लिखा गया है। यही कारण लागू होता है।)



0

किसी प्रकार T का 100-तत्व सरणी T टाइप के 100 स्वतंत्र चर को अलग करता है। यदि T एक मान प्रकार होता है, जिसमें Q का एक परिवर्तनशील सार्वजनिक क्षेत्र होता है और R का एक प्रकार होता है, तो सरणी का प्रत्येक तत्व स्वतंत्र चर को अलग कर देगा। Q और R प्रकार के प्रकार; एक पूरे के रूप में सरणी इस प्रकार प्रकार Q के 100 स्वतंत्र चर और प्रकार R के 100 स्वतंत्र चर को कूटबद्ध करेगा; किसी भी अन्य को प्रभावित किए बिना उनमें से किसी भी चर को व्यक्तिगत रूप से एक्सेस किया जा सकता है। सरणियों के अलावा कोई भी संग्रह प्रकार, संरचनाओं के क्षेत्रों को स्वतंत्र चर के रूप में उपयोग करने की अनुमति नहीं दे सकता है।

यदि T, Q और R के सार्वजनिक उत्परिवर्तनीय क्षेत्रों के साथ एक वर्ग प्रकार के बजाय हुआ, तो सरणी का प्रत्येक तत्व , उदाहरण के लिए, ब्रह्मांड में कहीं भी और कभी भी, सरणी के तत्वों में से कोई भी एकमात्र संदर्भ नहीं रखता है। Tकिसी ऐसी वस्तु की पहचान करने के लिए संशोधित किया जाना चाहिए जिसमें कोई भी बाहरी संदर्भ मौजूद है, तो सरणी प्रभावी रूप से टाइप Q के 100 स्वतंत्र चर और प्रकार R के 100 स्वतंत्र चर को अतिक्रमण करेगी। अन्य संग्रह प्रकार इस तरह के एक सरणी के व्यवहार की नकल कर सकते हैं, लेकिन यदि केवल उद्देश्य सरणी को Q के 100 वैरिएबल और टाइप R के 100 को एनकैप्सुलेट करना है, प्रत्येक जोड़े को अपनी ही क्लास ऑब्जेक्ट में बदलना यह करने का एक महंगा तरीका है। आगे की,किसी श्रेणी या परिवर्तनशील श्रेणी प्रकार के संग्रह का उपयोग करने से यह संभावना बनती है कि सरणी तत्वों द्वारा पहचाने गए चर स्वतंत्र नहीं हो सकते हैं

यदि एक प्रकार को किसी प्रकार की वस्तु के समान माना जाता है, तो यह या तो एक वर्ग प्रकार या एक निजी क्षेत्र की संरचना होनी चाहिए जो प्रतिस्थापन के अलावा अन्य उत्परिवर्तन का कोई साधन प्रदान नहीं करती है। यदि, हालांकि, एक प्रकार को संबंधित टेप का एक गुच्छा की तरह व्यवहार करने वाला माना जाता है, लेकिन डक्ट टेप के साथ-साथ स्वतंत्र चर, तो एक प्रकार का उपयोग करना चाहिए जो डक्ट टेप के साथ एक साथ अटके हुए चर का एक गुच्छा है - एक उजागर-क्षेत्र संरचना । इस तरह के एरे के साथ काम करने के लिए बहुत कुशल हैं, और बहुत साफ शब्दार्थ है। किसी भी अन्य प्रकार के उपयोग से मैला-कुचला शब्दार्थ, हीन प्रदर्शन, या दोनों हो जाएगा।


0

एक महत्वपूर्ण अलग मेमोरी आवंटन है। उदाहरण के लिए, लिंक की गई सूची को ट्रेस करने के परिणामस्वरूप बहुत सारे कैश मिस और धीमे प्रदर्शन हो सकते हैं, जबकि एक सरणी कुछ विशेष डेटा प्रकार के कई उदाहरणों को पकड़े हुए मेमोरी के एक सन्निहित हिस्सा का प्रतिनिधित्व करती है, और इसे क्रम में रखने से सीपीयू को हिट करने की अधिक संभावना है। कैश।

बेशक, वस्तु संदर्भों की एक सरणी कैश हिट्स से उतनी अधिक लाभान्वित नहीं हो सकती है, क्योंकि डेरेफेरेंसिंग अभी भी आपको मेमोरी में कहीं भी ले जा सकती है।

फिर ArrayList जैसे सूची कार्यान्वयन हैं, जो एक सरणी का उपयोग करके सूची को लागू करते हैं। वे उपयोगी आदिम हैं।


2
प्रश्न विशेष रूप से .Net प्रकार के बारे में पूछता है List<T>, जो एक लिंक की गई सूची का उपयोग करके कार्यान्वित नहीं किया जाता है, लेकिन एक सरणी का उपयोग करके (यह अनिवार्य रूप से ArrayList<T>जावा में समकक्ष है )।
svick

-2

यहां कुछ मार्गदर्शन दिए गए हैं, जिन पर आप चयन कर सकते हैं कि कब Arrayऔर कैसे चयन करना है List

  • Arrayकिसी विधि से लौटते समय उपयोग करें ।
  • Listचर के रूप में उपयोग करें जब आप रिटर्न वैल्यू (विधि के अंदर) का निर्माण कर रहे हैं। फिर .ToArray()विधि से लौटते समय उपयोग करें ।

सामान्य तौर पर, Arrayजब आप संग्रह में आइटम जोड़ने के लिए उपभोक्ता का इरादा नहीं रखते हैं तो उपयोग करें । उपयोग करें Listजब आप उपभोक्ता को संग्रह में आइटम जोड़ने का इरादा रखते हैं।

Array"स्थिर" संग्रहों Listसे निपटने के लिए है, जबकि "गतिशील" संग्रहों से निपटने के लिए है।


2
आपके द्वारा सुझाया गया नियम मनमाना है और अयोग्य कोड के परिणाम की संभावना है जो अनावश्यक नकल करता है। बहुत कम से कम आपको इसके लिए औचित्य के किसी रूप की आवश्यकता है।
जूल्स

@ जूल्स मुझे माइक्रो-ऑप्टिमाइज़ेशन की तुलना में डेवलपर अनुभव बहुत महत्वपूर्ण है। मुझे इस स्तर पर कभी भी प्रदर्शन की समस्या नहीं है।
डैनियल लिडस्ट्रॉम

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

@ जूल्स मुझे लगता है कि यह आपकी अपनी पसंद के हिसाब से नीचे आता है। मैं स्थिरांक के रूप में वापसी मूल्यों का इलाज करना पसंद करता हूं, जैसे कि मैं Arrayइसके बजाय उपयोग करना पसंद करता हूं List। हालांकि अपने विचारों को सुनकर अच्छा लगा!
डैनियल लिडस्ट्रॉम

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