2009-03-23 15 views
27

मैं एक निश्चित पैरामीटर के आधार पर आइटम खोजने के लिए एक सामान्य सूची देख रहा हूं।जेनेरिक सूची FindAll() बनाम foreach

जनरल में, क्या सबसे अच्छा और सबसे तेजी से कार्यान्वयन हो सकता है?
1. सूची में प्रत्येक आइटम के माध्यम से लूपिंग और एक नई सूची के लिए प्रत्येक मैच बचत और लौटने कि

foreach(string s in list) 
{ 
    if(s == "match") 
    { 
     newList.Add(s); 
    } 
} 

return newList; 

या
2. FindAll पद्धति का उपयोग करना है और यह एक प्रतिनिधि गुजर।

newList = list.FindAll(delegate(string s){return s == "match";}); 

क्या वे दोनों ओ (एन) में नहीं चलते हैं? यहां सबसे अच्छा अभ्यास क्या होगा?

सादर, जोनाथन

उत्तर

41

आपको निश्चित रूप से FindAll विधि, या समकक्ष LINQ विधि का उपयोग करना चाहिए। साथ ही, यदि आप कर सकते हैं तो अपने प्रतिनिधि के बजाय अधिक संक्षिप्त लैम्ब्डा का उपयोग करने पर विचार करें (सी # 3 की आवश्यकता है।0):

var list = new List<string>(); 
var newList = list.FindAll(s => s.Equals("match")); 
9

मैं, इस मामले में FindAll method का प्रयोग करेंगे के रूप में यह अधिक संक्षिप्त है, और IMO, आसान पठनीयता है।

आप सही है कि वे काफी दोनों जा रहे हैं (एन) समय हे में प्रदर्शन कर रहे हैं, हालांकि foreach statement होना चाहिए थोड़ा तेजी को देखते हुए यह एक प्रतिनिधि मंगलाचरण प्रदर्शन करने के लिए नहीं है (प्रतिनिधियों एक मामूली उठाना सीधे कॉलिंग विधियों के विरोध में ओवरहेड)।

मैं तनाव कैसे तुच्छ यह अंतर नहीं है, यह संभावना है कभी नहीं एक फर्क करने के लिए जब तक आप एक बड़े पैमाने पर सूची पर एक बड़े पैमाने पर संचालन की संख्या कर रहे हैं जा रहा से भी अधिक है की है।

हमेशा की तरह, परीक्षण जहां बाधाओं रहे हैं देख सकते हैं और उचित कार्रवाई करने में।

4

List.FindAll हे (एन) और पूरी सूची खोज करेंगे।

आप foreach के साथ अपने स्वयं इटरेटर चलाना चाहते हैं, मैं उपज कथन का उपयोग, और एक IEnumerable यदि संभव हो तो लौटने की सलाह देते हैं। इस तरह, यदि आप केवल अपने संग्रह के एक तत्व की आवश्यकता रखते हैं, तो यह तेज़ होगा (क्योंकि आप पूरे कॉलर को समाप्त किए बिना अपने कॉलर को रोक सकते हैं)।

अन्यथा, बीसीएल इंटरफ़ेस से चिपके रहते हैं।

3

किसी भी पर्फ़ अंतर बेहद मामूली होने जा रहा है। मैं स्पष्टता के लिए FindAll का सुझाव दूंगा, या, यदि संभव हो, तो गणना योग्य। कहाँ। मैं संख्यात्मक तरीकों का उपयोग करना पसंद करता हूं क्योंकि यह कोड को पुन: सक्रिय करने में अधिक लचीलापन की अनुमति देता है (आप List<T> पर निर्भरता नहीं लेते हैं)।

5

जोनाथन,

एक अच्छा जवाब आप इस के लिए मिल सकता है Linq To Action के अध्याय 5 (प्रदर्शन विचार) में है।

वे प्रत्येक खोज के लिए मापते हैं जो लगभग 50 गुना निष्पादित करता है और यह प्रति चक्र/सूची के लिए foreach = 68ms के साथ आता है। फिंडल = 62ms प्रति चक्र। असल में, यह शायद एक परीक्षा बनाने और खुद के लिए देखने के लिए आपकी रुचि में होगा।

2

हां, वे दोनों कार्यान्वयन ओ (एन) हैं। उन्हें सभी मैचों को खोजने के लिए सूची में प्रत्येक तत्व को देखने की आवश्यकता है। पठनीयता के मामले में मैं FindAll भी पसंद करूंगा। प्रदर्शन विचारों के लिए LINQ in Action (सी 5.3) पर एक नज़र डालें। यदि आप सी # 3.0 का उपयोग कर रहे हैं तो आप लैम्ब्डा अभिव्यक्ति भी लागू कर सकते हैं। लेकिन यह सिर्फ केक पर टुकड़े है:

var newList = aList.FindAll(s => s == "match"); 
0

जब तक सी # टीम LINQ और FindAll के लिए प्रदर्शन में सुधार हुआ है साथ मैं, निम्न आलेख सुझाव देने के लिए लगता है कि for और foreach ऑब्जेक्ट गणना पर LINQ और FindAll से अधिक प्रदर्शन करेगा: LINQ on Objects Performance

यह कला मूल रूप से पूछे जाने से ठीक पहले, मार्च 200 9 की तारीख थी।

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