2009-10-27 12 views
6

क्या प्रदर्शन बुद्धिमान foreach बयान के बाहर चर और हर बार यह (foreach) पक्ष में पुन: असाइन घोषित करने के लिए बेहतर या उदाहरणforeach, प्रदर्शन के अनुसार। क्या हमें लूप या उसके अंदर एक बार वैरिएबल घोषित करना चाहिए?

private List<ListItem> GetItems() 
     { 
      var items = new List<ListItem>(); 
      var collection = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 
      ListItem item; 
      foreach (var i in collection) 
      { 
       item = new ListItem { Text = i.ToString() }; 
       items.Add(item); 
      } 

      return items; 
     } 

या इस एक के लिए foreach के अंदर एक नया चर बना है?

private List<ListItem> GetItems() 
     { 
      var items = new List<ListItem>(); 
      var collection = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 
      foreach (var i in collection) 
      { 
       ListItem item = new ListItem { Text = i.ToString() }; 
       items.Add(item); 
      } 

      return items; 
     } 

यकीन है कि यहाँ मैं आइटम वस्तु के बारे में बात करते हैं। आपको सभी का धन्यवाद।

उत्तर

12

यह premature optimization जैसा लगता है।

सबसे पहले, क्या आपके पास यह मानने का कोई कारण है कि यहां कोई प्रदर्शन समस्या है?

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

4

मुझे पूरा यकीन है कि आपके दो कोड ब्लॉक द्वारा उत्पन्न आईएल समान है। प्रदर्शन में कोई बदलाव नहीं होना चाहिए। हालांकि दूसरा कोड ब्लॉक जहां आप आइटम का प्रकार कहां घोषित करते हैं, इसका उपयोग थोड़ा और पठनीय है और मैं इसका उपयोग करूंगा।

3

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

बेशक, आप भी संग्रहीत संदर्भ के सभी एक साथ छुटकारा सकता हो:

private List<ListItem> GetItems() 
{ 
    var items = new List<ListItem>(); 
    var collection = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 

    foreach (var i in collection) 
    { 
    items.Add(new ListItem { Text = i.ToString() }); 
    } 

    return items; 
} 
+0

यह आमतौर पर है कि मुझे क्या करना। यह आत्म सेवारत है, इसलिए मैं आप वोट दें देंगे: डी –

0

शायद एक ही कोड को संकलित करता है लेकिन क्यों यह redeclaring परेशान। इस मामले में संदर्भ के बारे में यह अच्छी बात है। एक बार जब आप इसके साथ काम कर लेंगे तो आप इसे किसी अन्य ListItem को असाइन कर सकते हैं और जीसी बाकी का ख्याल रखता है।

लेकिन अन्य प्रोग्रामर के लिए दूसरी तरफ पठनीयता। यह एक ऐसा निर्णय है जो निश्चित रूप से आपके अनुप्रयोग प्रदर्शन को बहुत अधिक नहीं बदलेगा।

0

अपने मामले में और भी बेहतर है:

private List<ListItem> GetItems()   
{    
    var items = new List<ListItem>();    
    var collection = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };    
    foreach (var i in collection)    
     items.Add(new ListItem { Text = i.ToString() });     
    return items;   
} 

क्यों सब पर एक अतिरिक्त चर बना?

1

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

कुछ की तरह:

private List<ListItem> GetItems() 
    { 
     var collection = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 
     var items = new List<ListItem>(collection.Count); //declare the amount of space here 

     foreach (var i in collection) 
     { 
      ListItem item = new ListItem { Text = i.ToString() }; 
      items.Add(item); 
     } 

     return items; 
    } 
0

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

गुंजाइश और कोड की है कि ब्लॉक के संदर्भ ज्यादा छोटे प्रदर्शन अनुकूलन है कि प्रकृति में समय से पहले और इस परिदृश्य में अनावश्यक होगा से ज्यादा महत्वपूर्ण है।

7

वहाँ बढ़त मामले में जहां यह मायने रखती है; यदि आप "कब्जा" एक गुमनाम विधि/लैम्ब्डा में चर। अन्यथा यह समय से पहले है और कोई फर्क नहीं पड़ता। बिलकुल।

जब यह फर्क पड़ता है का एक उदाहरण:

// prints all items in no particular order 
foreach (var i in collection) 
{ 
    string s = i.ToString(); 
    ThreadPool.QueueUserWorkItem(delegate { Console.WriteLine(s); }); 
} 

बनाम

// may print the same item each time, or any combination of items; very bad 
string s; 
foreach (var i in collection) 
{ 
    s = i.ToString(); 
    ThreadPool.QueueUserWorkItem(delegate { Console.WriteLine(s); }); 
} 
संबंधित मुद्दे