2009-10-27 81 views
6

什麼是性能明智的聲明每次在側它(的foreach)重新分配它在foreach statment外的變量,並更好或建立內部的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; 
     } 

或這一個?

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

我很確定你的兩個代碼塊產生的IL是相同的。性能不應該有任何變化。然而,第二個代碼塊在哪裏你聲明使用它的地方的項目的類型是稍微可讀的,我會使用它。

3

這是一個非常微觀的優化,如果不生成相同的代碼,兩種方法在性能上可能完全相同。在這種情況下,請閱讀。我更喜歡第二個,因爲你的對象不在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) 
    { 
    items.Add(new ListItem { Text = i.ToString() }); 
    } 

    return items; 
} 
+0

這通常是我做的。這是自我服務,所以我會upvote你:D – 2009-10-27 17:50:39

0

可能編譯成相同的代碼,但是爲什麼還要重新聲明它。 這是參考文獻的好處,在這種情況下是項目。 完成後,您可以將其分配給另一個ListItem,GC 負責其餘部分。

但在另一方面對其他程序員的可讀性。這是一個決定,當然不會大幅改變你的應用程序性能。

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

由兩個塊創建的IL應該幾乎相同。如果你正在尋找優化,我會在填充項目之前考慮設置最終列表的長度。這樣你就不會成爲延長列表長度的擴張懲罰。

喜歡的東西:

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

因爲每個人都有猜測,該IL將是相同的。另外,正如其他人所說,在他們成爲問題之前不要擔心這樣的事情。相反,問問自己該變量的範圍在哪裏。

該代碼塊的範圍和上下文比小型性能優化要重要得多,這種優化本質上是不成熟的,在這種情況下是不必要的。

7

還有這個問題的邊緣情況;如果你將變量「捕獲」到匿名方法/ lambda中。否則,它是不成熟的,沒有區別。完全一樣。

無論何時它的一個例子:

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

VS

// 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); }); 
} 
相關問題