2009-06-25 12 views

उत्तर

55

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

एक प्रत्यक्ष foreach दृष्टिकोण कई मामलों में LINQ से तेज़ होगा। उदाहरण के लिए, पर विचार करें:

var query = from element in list 
      where element.X > 2 
      where element.Y < 2 
      select element.X + element.Y; 

foreach (var value in query) 
{ 
    Console.WriteLine(value); 
} 

अब दो where खंड और एक select खंड हैं, इसलिए हर अंतिम आइटम तीन iterators के माध्यम से पारित करने के लिए है।

foreach (var element in list) 
{ 
    if (element.X > 2 && element.Y < 2) 
    { 
     Console.WriteLine(element.X + element.Y); 
    } 
} 

कि तेजी से चलाया जाएगा, क्योंकि यह हैं: (। जाहिर है दो जहां खंड इस मामले में जोड़ा जा सकता है, लेकिन मैं एक सामान्य मुद्दा बना रहा हूँ)

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

संपादित करें: के बारे में "नेस्टेड foreach" उत्तर देने के लिए लूप ... आम तौर पर उन SelectMany या एक दूसरे from खंड के साथ प्रतिनिधित्व कर रहे हैं:

var query = from item in firstSequence 
      from nestedItem in item.NestedItems 
      select item.BaseCount + nestedItem.NestedCount; 

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

यह कहना नहीं है कि आप स्वयं को LINQ के साथ पैर में शूट नहीं कर सकते हैं। यदि आप पहले अपने दिमाग को व्यस्त नहीं करते हैं तो आप शानदार अक्षम प्रश्न लिख सकते हैं - लेकिन यह अद्वितीय से LINQ तक है ...

+13

पहला वाक्य एक बैनर के रूप में बाहर मुद्रित किया जाना चाहिए और हर प्रोग्रामिंग विभाग में लटका दिया। –

+1

जॉन ... आप कमाल हैं ... हार्दिक धन्यवाद !! –

11

यह उस पर अधिक जटिल है। आखिरकार, LINQ-to-Objects के अधिकांश (दृश्यों के पीछे) foreach लूप है, लेकिन थोड़ा अबास्ट्रक्शन/इटरेटर ब्लॉक/आदि के अतिरिक्त ओवरहेड के साथ, हालांकि, जब तक आप अपने दो संस्करणों में बहुत अलग चीजें नहीं करते हैं (foreach बनाम LINQ), वे दोनों ओ (एन) होना चाहिए।

असली सवाल यह है: वहाँ इसका मतलब है कि foreach अक्षम होगा अपने विशिष्ट एल्गोरिथ्म लिखने के लिए एक बेहतर तरीका है? और LINQ आपके लिए यह कर सकता है?

उदाहरण के लिए, LINQ हैश/समूह/सॉर्ट डेटा को आसान बनाता है।

22

यदि आप करते हैं

foreach(Customer c in Customer) 
{ 
    foreach(Order o in Orders) 
    { 
    //do something with c and o 
    } 
} 

आप Customer.Count * आदेश प्रदर्शन करेंगे।पुनरावृत्तियों


यदि आप करते हैं

var query = 
    from c in Customer 
    join o in Orders on c.CustomerID equals o.CustomerID 
    select new {c, o} 

foreach(var x in query) 
{ 
    //do something with x.c and x.o 
} 

आप Customer.Count + Order.Count पुनरावृत्तियों प्रदर्शन करेंगे गणना, क्योंकि Enumerable.Join एक HashJoin के रूप में कार्यान्वित किया जाता है।

+0

एक अच्छा स्पष्टीकरण के साथ महान उत्तर –

+4

ऐसा इसलिए है क्योंकि आप दो अलग-अलग एल्गोरिदम चला रहे हैं; आप संतरे से सेब की तुलना कर रहे हैं। मैं नहीं देखता कि यह प्रश्न के लिए प्रासंगिक कैसे है। – mquander

+3

आपका घोंसला वाला foreach वास्तव में SelectMany के बराबर है, शामिल नहीं है - यानी ग्राहक से ऑर्डर में ग्राहक से ... (कोई भी शामिल नहीं) –

2

यह पहले भी कहा गया है, लेकिन यह गुण दोहरा।

डेवलपर्स कभी पता नहीं जहां प्रदर्शन टोंटी है, जब तक वे प्रदर्शन परीक्षण चला।

उसी तकनीक बी तकनीक एक की तुलना के लिए सही जब तक एक नाटकीय अंतर नहीं है तो आप बस इसे परीक्षण करने के लिए है। यह स्पष्ट हो सकता है कि आपके पास ओ (एन) बनाम ओ (एन^एक्स) परिदृश्य है, लेकिन चूंकि LINQ सामान ज्यादातर कंपाइलर जादूविद है, यह एक प्रोफाइलिंग योग्यता है।

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

+1

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

2

एक बड़ा लाभ यह है कि लिंक-टू-ऑब्जेक्ट्स क्वेरीज का उपयोग करके आप क्वेरी को आसानी से PLinq पर बदल सकते हैं और सिस्टम को स्वचालित रूप से वर्तमान सिस्टम के लिए सही संख्या में धागे पर ऑपरेशन करने की क्षमता मिलती है।

आप बड़े डेटासेट पर इस तकनीक का उपयोग कर रहे हैं, कि एक आसानी से बहुत कम परेशानी के लिए एक बड़ी जीत बन गया है।

+0

सच है लेकिन साथ ही साथ समानांतर समकक्ष भी प्रस्तावित हैं। http://www.danielmoth.com/Blog/2009/01/parallelising-loops-in-net-4.html – jpierson