2012-02-14 10 views
23

विजुअल स्टूडियो री-शार्पर में अनुशंसा करता रहता है कि मैं लूप को एक लिनक्स अभिव्यक्ति में रूपांतरित कर दूं लेकिन इसका कारण क्या है?रीशेर्पर का सुझाव है कि मैं लूप को एक LINQ अभिव्यक्ति में रूपांतरित करता हूं?

कौन सा तेज़ है?

foreach (XmlNode legendEntryNode in _legendEntryNodes) 
{ 
    var xmlElement = legendEntryNode["FeatureType"]; 

    if (xmlElement == null || !xmlElement.InnerText.Equals(featuretype)) continue; 

    var xmlNodeList = legendEntryNode.SelectNodes("Themes/Theme"); 

    if (xmlNodeList != null) 

    foreach (XmlNode themeNode in xmlNodeList) 
    { 
     var element = themeNode["Value"]; 

     if (element == null || !element.InnerText.Equals(v)) continue; 

     var xmlElement1 = themeNode["Icon"]; 

     if (xmlElement1 != null) 
     { 
      string iconname = "<ms:ICON>" + xmlElement1.InnerText + "</ms:ICON>"; 

      var element1 = themeNode["Highlight"]; 

      if (element1 != null) 
      { 
       string highlightname = "<ms:HIGHLIGHT>" + element1.InnerText + "</ms:HIGHLIGHT>"; 
       gml = gml.Insert(c, iconname + highlightname); 

       c += (iconname.Length + highlightname.Length); 
      } 
     } 
     break; 
    } 
} 

और यह सरल उदाहरण:

यहां कुछ उदाहरण लूप जहां ReSharper एक LINQ रूपांतरण का सुझाव हैं

for (int i = 0; i < getPointsRequest.Attribs.Length; i++) 
{ 
    string attribName = getPointsRequest.Attribs[i].AttributeName; 

    if (!String.IsNullOrEmpty(attribName)) 
    { 
     sqlQuery += "<ms:" + attribName + ">||\"" + attribName + "\"||</ms:" + attribName + ">"; 
    } 
} 
+0

आप हमें एक उदाहरण लूप दिखाना चाहते हैं। –

+1

कुछ उदाहरण जोड़े गए – CSharpened

+1

बस एक मामूली छोटी बात, मुझे पता है कि ये उदाहरण हैं लेकिन आप स्ट्रिंग कॉन्सटेनेशन को 'string.Format' में बदलना चाहते हैं, इसलिए सरल उदाहरण बन जाता है:' sqlQuery + = string.Format (" || \ "{0} \" || ", attribName); ', जो पढ़ने में आसान है। Resharper उन्हें बदलना आसान बनाता है क्योंकि यह इसके रिफैक्टरिंग विकल्पों में से एक है। –

उत्तर

36

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

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

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

यदि आपके कुछ ठोस उदाहरण हैं, तो हम अधिक राय दे सकते हैं कि कौन सी लूप LINQ उपयोग करने के लिए परिवर्तित करने के लिए समझ में आएगी, और जो नहीं।

+0

का चयन करें, मैंने यह माना होगा कि हालांकि एक साधारण लूप की गति प्रतीत हो सकती है अप्रासंगिक लेकिन निश्चित रूप से इन सभी अप्रासंगिक स्थानों की भव्य योजना में प्रदर्शन में एक बड़ा अंतर है? – CSharpened

+7

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

+0

इसके लिए ठीक है धन्यवाद। इसकी प्रशंसा करना। कई लोगों की तुलना में अपेक्षाकृत नए डेवलपर होने के नाते मैं कभी-कभी ऐसी चीजों को अनदेखा करता हूं जैसे अक्सर मुझे एक परियोजना के एक छोटे से हिस्से के साथ काम मिल जाता है और इस तरह यह सुनिश्चित करना चाहता है कि मेरा हिस्सा 100% आवश्यकताओं को पूरा करते हुए आसानी से और जल्दी से चलता है। – CSharpened

4

यह संभव वहाँ गति में कोई अंतर नहीं है कि है, लेकिन का उपयोग कर Linq अक्सर परिणाम कर सकते हैं terser कोड में। यह कहना नहीं है कि आपको हमेशा लिंक अभिव्यक्ति में कनवर्ट करने के लिए आर # के सुझाव को स्वीकार करना चाहिए। कभी-कभी जटिल लेकिन समझने योग्य foreach loops को वैध रूप में परिवर्तित कर दिया जाता है लेकिन आसानी से लिंक अभिव्यक्ति को नहीं समझा जाता है।

+0

तकनीक के लिए एक लूप अभिव्यक्ति की आवश्यकता होती है क्योंकि तकनीकी रूप से एक लूप हमेशा तेज होता है। – Polity

+0

यह मेरे साथ मुख्य मुद्दों में से एक है। मैं वास्तव में linq के साथ गति करने के लिए नहीं हूं और नतीजतन मुझे कुछ परिवर्तित कोड पढ़ने के लिए मुश्किल लगता है जो वास्तव में विपरीत प्रभाव पड़ता है कि resharper सबसे अधिक संभावना है। मुझे संदेह है कि यह अन्य देवताओं के साथ भी वही होगा जो लिनक का भी उपयोग नहीं करते हैं और मेरे कोड के भाग को उन लोगों को पढ़ने में मुश्किल हो सकते हैं जो लिनक के साथ गति तक नहीं हैं। – CSharpened

+1

linq का पूरा बिंदु कम terse, अधिक पठनीय कोड है - यह कुछ मामलों में terse हो सकता है या तो असाधारण मामला या पाठक की विफलता कार्यात्मक/घोषणात्मक कोड की सराहना करने के लिए है। आप मूल रूप से कभी भी फ़ोरैच लूप के रूप में लिनक कोड लिखना नहीं चाहते हैं: चयन में एस से। ShapeRange.Cast () जहां s.IsSomething() s.Name – PandaWood

2

हाय लिंक वास्तव में आंतरिक रूप से लूप के लिए कॉल कर रहा है। मुझे लगता है कि यह नीचे आता है कि लिंक अभिव्यक्तियों को पढ़ने/बनाए रखने के लिए सामान्य रूप से आसान है। http://geekswithblogs.net/BlackRabbitCoder/archive/2010/04/23/c-linq-vs-foreach---round-1.aspx

15

जैसे कोई प्रदर्शन लाभ है, लेकिन कुछ लाभ

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

अधिक जानकारी के लिए आप उल्लेख कर सकते हैं:

आशा यह आप में मदद करता है।

+0

महान उत्तर, धन्यवाद। – CSharpened

+1

कोई प्राकृतिक भाषा के करीब एक कोड लिखना पसंद करेगा ... जाहिर है, LINQ ऐसा करने में मदद करता है ... – Umer

3

सामान्य रीशेर्पर के सुझाव केवल सुझाव और कोई चेतावनी नहीं हैं। तो यह तय करने के लिए आप पर निर्भर है कि आप किस तरह से जाते हैं: LINQ या foreach।
मुझे "उपयोग 'var' सुझाव के साथ एक ही समस्या है। मैं केवल उस सुझाव पर क्लिक करता हूं अगर मुझे लगता है कि पाठक बेहतर बयान पढ़ सकता है।
कोड लिखते समय पठनीयता मेरी सर्वोच्च प्राथमिकताओं में से एक है।

3

मैं कहूंगा कि कभी-कभी परिवर्तित नहीं होने का एक कारण है। यह शायद कम प्रशंसनीय है कि रीशेपर एक LINQ अभिव्यक्ति (पीछे) को फॉर-लूप में बदलने के लिए एक रिफैक्टरिंग प्रदान नहीं करता है। मैंने कुछ मौकों पर एक लूप को अभिव्यक्ति में परिवर्तित कर दिया है और बाद में लूप के भीतर कुछ और कार्रवाइयों (अक्सर डीबगिंग क्रियाएं) डालना चाहता था; मुझे उन्हें हाथ से वापस बदलना है।

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

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

[क्षमा करें यह पोस्ट ज्यादातर राय है, लेकिन पठनीयता एक व्यक्तिपरक विषय का थोड़ा सा है। कोई trolling!]

0

दूसरों के लिए संदर्भ के रूप में, यहाँ की Resharper

for (int x = 0; x < grid.Length; x++) 
     { 
      var intCount = grid[x].Select((a, b) => new {Value = a, Index = b}) 
       .GroupBy(y => y.Value) 
       .Where(y => y.Count() > 1).Select(item => item.Key).ToArray(); 

      if (intCount.Count() > 1) 
       return false; 
     } 

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

यह LINQ में पाश के लिए सुझाव दिया है:

return grid.Select(t => t.Select((a, b) => new {Value = a, Index = b}). 
      GroupBy(y => y.Value).Where(y => y.Count() > 1). 
      Select(item => item.Key).ToArray()).All(intCount => intCount.Count() <= 1); 

कोई निष्पादन लाभ हो सकता है, लेकिन जैसा कि आप उदाहरण से देख सकते हैं, एक LINQ क्वेरी क्लीनर, पढ़ने के लिए, कम लाइनों आसान है (जो इस मामले में, कोड की केवल एक पंक्ति, मैंने इसे यहां चिपकाने के बाद इसे समायोजित किया) और डीबग करने में भी आसान है।