2009-12-01 8 views
17

संभव डुप्लिकेट:
Is it better to call ToList() or ToArray() in LINQ queries?मुझे फिर से शुरू करने और गिनने की आवश्यकता है। सबसे तेज़ या पसंदीदा क्या है: ToArray() या ToList()?

मैं इस तरह कोड है:

void Foobar(string[] arr, Dictionary<string, string[]>) 
{ 
    var t = arr.Intersect(dic.Keys).ToList(); // .or ToArray() ? 
    foreach(var item in t) 
    { 
     .. 
    } 

    var j = t.Count; // also I need this 
} 

जो विधि को प्राथमिकता दी जाती है?

मैं किसी भी बिना जा सकते हैं, लेकिन मैं आकार पता करने की जरूरत है और मैं Enumerable.Count<T>() कॉल करने के लिए नहीं करना चाहते हैं - इसे और अधिक कार्रवाई तब Array<T>.Size या List<T>.Count करते हो लगता है। क्या मैं सही हू?

+0

संबंधित: [LINQ प्रश्नों में ToList() या ToArray() को कॉल करना बेहतर है?] (Http://stackoverflow.com/questions/1105990/is-it-better-to-call-tolist-or- toarray-in-linq-query) – GSerg

उत्तर

16

असल में, वर्तमान एमएस कार्यान्वयन के गणना में (आईनेमरेबल) में एक शॉर्टकट है जो देखता है कि आईन्यूमेरेबल एक आईसीओलेक्शन है और उस पर गणना करें। तो प्रदर्शन तत्वों की गणना के लिए तुलनीय होना चाहिए।

ToList और ToArray थोड़ा समान हैं। यदि IENumerable एक ICollection है, तो CopyTo विधि को इसके बजाय कहा जाता है, जो थोड़ा तेज़ है।

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

अद्यतन: मैंने एक बेवकूफ बेंचमार्क किया था।

किसी सरणी के साथ शुरू: var items = Enumerable.Range(1,1000).ToArray();

  • बुला ToList(): 25ms/10000
  • toArray बुला(): 23 एमएस/10000

एक IEnumerable के साथ शुरू: var items = Enumerable.Range(1,1000);

  • कॉललिस्ट टूलीस्ट(): 168ms/10000
  • toArray बुला(): 171 एमएस/10000

तो बुनियादी तौर पर आप तुलनीय प्रदर्शन मिलता है।

11

अंतर शायद इतना छोटा है कि यह केवल उस विधि का उपयोग करने योग्य है जो आपकी आवश्यकताओं को बेहतर तरीके से फिट करता है। सूक्ष्म अनुकूलन की बदबू आ रही है।

और इस मामले में, आप जो भी कर रहे हैं, वह सेट को गिन रहा है और सेट को गिन रहा है (दोनों जिनमें से आप एक आईनेमरेबल के साथ कर सकते हैं), क्यों न केवल इसे एक आईनेमेरेबल <> के रूप में छोड़ दें?

+0

मुझे लगता है कि यह स्वाभाविक रूप से किसी अन्य प्रश्न के लिए जाता है: चूंकि प्रदर्शन अधिकांश उद्देश्यों और उद्देश्यों के लिए समान है, तो मुझे किस प्रकार का "डिफ़ॉल्ट" संग्रह प्रकार के रूप में उपयोग करना चाहिए? मैं व्यक्तिगत रूप से 'सूची ' पसंद करता हूं क्योंकि यह केवल लंबाई में पढ़ा नहीं जाता है, लेकिन मुझे अतीत में दूसरों को यह विश्वास दिलाता है कि यह 'टी [] 'से बेहतर" डिफ़ॉल्ट "संग्रह प्रकार विकल्प बनाता है। –

+0

@romkyns: बिल्कुल, यह आम तौर पर उपयोग करने के लिए एक डिफ़ॉल्ट वर्ग के बारे में है। और मैं एक निश्चित लंबाई के संग्रह के रूप में एक सरणी पसंद करते हैं। मैं केवल गतिशील-लंबाई का उपयोग करता हूं जब इसे स्पष्ट रूप से – abatishchev

12

यदि आप वास्तव में प्रदर्शन के बारे में चिंतित हैं, तो आपको IEnumerable पर लूप करना चाहिए और इसे जाने के रूप में गिनना चाहिए। यह पूरी तरह से एक नया संग्रह बनाने के लिए होने बचा जाता है, और चौराहे केवल एक बार दोहराया जाना है:

void Foobar(string[] arr, Dictionary<string, string[]>) 
{ 
    var t = arr.Intersect(dic.Keys); 
    int count = 0; 
    foreach(var item in t) 
    { 
     count++; 
     .. 
    } 

    var j = count; 
} 

लेकिन किसी और की तरह ने कहा: इस माइक्रो अनुकूलन के बदबू आ रही है। यदि प्रदर्शन इस स्थिति में वास्तव में महत्वपूर्ण है, कम से कम प्रदर्शन प्रोफाइलिंग करना यह पता लगाने के लिए कि कौन सी विधि वास्तव में आपके लिए सबसे तेज़ है।

+1

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

+5

@Yaakov: कुछ संग्रह के आकार की गणना करने के लिए होगा। खुद को गिनने के द्वारा, आपको केवल एक बार संग्रह पर फिर से प्रयास करना होगा। यदि संग्रह सूची की सरणी में परिवर्तित हो जाता है, तो संग्रह को कम से कम दो बार (एक बार रूपांतरण के लिए, और एक बार 'foreach' लूप' के लिए हस्तक्षेप किया जाना चाहिए। – Greg

+1

परावर्तक के अनुसार, सूची <>, ArrayList <> और प्रत्येक धार ऑब्जेक्ट के भीतर एक लंबाई या आकार चर जो सीधे गणना करते समय संदर्भित किया जाता है - इसलिए एक ऐरे या सूची पर चलने वाली गणना किसी अन्य गणना का कारण नहीं बनती। –

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

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