2010-02-03 5 views
8

मैं फिर से कारक के बारे में सोच रहा हूं, लेकिन मुझे नहीं पता कि अंतिम परिणाम केवल ओवरकिल है या नहीं। वर्तमान में मैंइस स्थिति में link का उपयोग कर रहा है overkill

IList<myobjecttypebase> m_items; 

    public int GetIncrementTotal() 
    { 
    int incrementTot; 
    foreach(myobjecttypebase x in m_items) 
    { incrementTot += x.GetIncrement(); } 
    } 

है यह overkill और/या डाली यहाँ एक महत्वपूर्ण ओवरहेड होगा foreach

m_items.ToList().ForEach(x => incrementTot += x.GetIncrement()); 

के लिए LINQ का उपयोग करने के कम कुशल होगा?

उत्तर

4

ToList विधि LINQ के साथ प्रयोग किया एक विस्तार तरीका है, लेकिन foreach विधि सिर्फ एक तरीका है सूची वर्ग में।

यहां प्रमुख ओवरहेड टूलीस्ट विधि का आह्वान है, जो संग्रह से एक नई सूची बनाता है। फॉरएच में थोड़ी सी ओवरहेड भी है क्योंकि इसे प्रत्येक आइटम के लिए एक प्रतिनिधि को कॉल करना है।

आप LINQ तरीकों का उपयोग करना चाहते हैं, सकल विधि अधिक उपयुक्त लगता है:

public int GetIncrementTotal() { 
    return m_items.Aggregate(0, (t, i) => t + i.GetIncrement()); 
} 

या सम:

public int GetIncrementTotal() { 
    return m_items.Sum(i => i.GetIncrement()); 
} 

या तो, अपने मूल संस्करण पर एक मामूली भूमि के ऊपर है, इसलिए यदि आप चाहते हैं सबसे कुशल, बस एक साधारण पाश के लिए छड़ी।

+0

व्यापक उत्तर Guffa के लिए धन्यवाद। – Andrew

+0

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

3

ओवरहेड संग्रह को दो बार फिर से करने में होगा।

m_items.ToList() // First iteration to add to the list all the items 
    .ForEach(x => incrementTot += x.GetIncrement()); /* Second iteration to 
                 perform logic */ 

ToList सबसे LINQ बयान के रूप में आलसी तरीके से यात्रा प्रदर्शन नहीं करता, तो इसके यह संग्रह से अधिक कोड पुनरावृति दो बार बाध्य करेगा।

सामान्य रूप से LINQ फॉर्म पढ़ने के लिए अच्छा लगता है, लेकिन यदि आप प्रदर्शन के बारे में चिंता कर रहे हैं तो आप इससे बेहतर बचें।

+0

मुझे लगता है कि linq संस्करण ओवरहेड वाला एक होगा। यदि ऐसा है तो ToList() विधि को IList – Andrew

+0

@Andrew से डालने के लिए गणना के दौरान फिर से शुरू करने की आवश्यकता क्यों होगी - क्योंकि इसे संग्रह को सूची में परिवर्तित करने की आवश्यकता है। – Oded

+0

@Andrew: ToList() विधि एक कास्ट नहीं है। यह एक रूपांतरण विधि है और एक नई सूची <> ऑब्जेक्ट आवंटित और पॉप्युलेट करेगा। –

7

क्यों SUM ऑपरेटर का उपयोग सीधे IList पर नहीं करें?

यह Func प्रतिनिधियों का उपयोग कर कई भार के है:

m_items.Sum(x => x.GetIncrement()); 
+0

GetIncrement विधि बेस क्लास पर एक सार विधि है और विभिन्न ठोस कार्यान्वयन वृद्धि मूल्य को ओवरराइड करते हैं। अन्यथा मैंने अभी इस्तेमाल किया होगा। IList – Andrew

+0

पर गणना() उत्तर नहीं बदलता है ... – Oded

+0

मैं नीचे जॉन के कोड नमूने के लिए आपका बिंदु धन्यवाद देखता हूं। – Andrew

1

यह इस तरह से मत करो।
ToList() यहां एक नई सूची आवंटित और पॉप्युलेट करेगा, आईएमएचओ आवश्यक नहीं है। हालांकि, यह किसी भी ऑब्जेक्ट पर पुनरावृत्ति करने के लिए फॉरएच एक्सटेंशन विधि लिखने के लिए एक छोटा अभ्यास है, लेकिन मैं इसके खिलाफ सलाह दूंगा (एरिक लिपर्ट foreach V's ForEach द्वारा इस आलेख को देखें)।

मैं foreach के साथ जाना होगा।

पीएस आप incrementTot आरंभ करने के लिए (क्षमा करें, मैं अपने आप को मदद नहीं कर सकता है)

2

जरूरत Oded उल्लेख उपयोग योग

incrementTot = m_items.ToList().Sum(x => x.GetIncrement()); 
+2

यदि आप जो कुछ करने जा रहे हैं, वह मूल्यों को जोड़ना क्यों है? उदाहरण के लिए –

+0

धन्यवाद। ओडेड का मतलब मुझे नहीं मिला क्योंकि मैं लिनक के लिए अपेक्षाकृत नया हूं। – Andrew

+0

जॉन स्कीट एक बार के लिए सही है। Tolist अनिवार्य है। –

3

ForEach LINQ का हिस्सा नहीं है के रूप में - यह List<T> एपीआई का हिस्सा है और के बाद से किया गया है। नेट 2.0।

कारण यह LINQ का हिस्सा नहीं है क्योंकि यह स्वाभाविक रूप से साइड-इफेक्टिंग विधि है ... और LINQ साइड इफेक्ट्स को प्रोत्साहित नहीं करता है।

सही समाधान योग का प्रयोग किया जाता है यहाँ है, लेकिन आप पहली बार एक सूची बनाने की जरूरत नहीं है:

return m_items.Sum(x => x.GetIncrement()); 
संबंधित मुद्दे