2009-10-27 3 views
6

Was ist besser für die Leistung wiese den Variable außerhalb des foreach statment erklärt und das jedes Mal, wenn in Seiten es (foreach) neu zuweisen oder eine neue Variable in foreach zum Beispiel erstellenforeach, leistungsmäßig. Sollten wir die Variable einmal vor oder in der Schleife deklarieren?

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; 
     } 

oder dies?

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; 
     } 

sicher hier bin ich über Gegenstand Gegenstand sprechen. danke euch allen.

Antwort

12

Das klingt wie ein premature optimization.

Vor allem, haben Sie irgendeinen Grund zu der Annahme, dass es hier ein Leistungsproblem gibt?

Zweitens, in Release-Builds, der Compiler Optimierer wird wahrscheinlich identische Code für beide Szenarien produzieren - so ist es wahrscheinlich irrelevant. In Debug-Builds ist dies möglicherweise nicht immer der Fall, aber Sie möchten keine Optimierungen vornehmen, da die Absicht von Debug-Builds darin besteht, dass Sie den Code genau durchgehen können.

4

Ich bin mir ziemlich sicher, dass die von Ihren beiden Codeblöcken erzeugte IL identisch ist. Es sollte keine Leistungsänderung geben. Allerdings ist der zweite Codeblock, in dem Sie den Typ des Elements genau dort angeben, wo es verwendet wird, etwas lesbarer und würde ich verwenden.

3

Dies ist eine sehr Mikro-Optimierung und beide Methoden werden wahrscheinlich genau die gleiche Leistung, wenn nicht identische Code generieren. In diesem Fall sollten Sie auf Lesbarkeit achten. Ich würde die zweite bevorzugen, da Ihr Objekt außerhalb der foreach-Schleife keinen Zweck erfüllt.

Argumentieren, können Sie auch alle zusammen von der gespeicherten Referenz loszuwerden:

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

Dies ist in der Regel, was ich tue. Es ist eigennützig, also werde ich dich aufmuntern: D –

0

Wahrscheinlich kompilieren auf den gleichen Code aber warum es die Mühe erneut deklariert werden. Das ist das Schöne an der Referenz, in diesem Fall Artikel. Sobald Sie damit fertig sind, können Sie es einem anderen ListItem zuweisen und der GC kümmert sich um den Rest.

Aber auf der anderen Seite Lesbarkeit für andere Programmierer. Es ist eine Entscheidung, die Ihre Anwendungsleistung sicherlich nicht drastisch ändert.

0

Noch besser in Ihrem Fall ist:

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;   
} 

Warum überhaupt eine zusätzliche Variable erstellen?

1

Die von den zwei Blöcken erstellte IL sollte fast die gleiche sein. Wenn Sie optimieren möchten, würde ich die Länge der endgültigen Liste festlegen, bevor Sie sie mit Elementen füllen. Auf diese Weise werden Sie nicht die Erweiterungsstrafe für die Verlängerung der Liste sein.

Etwas wie:

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

Wie jeder spekuliert hat, wird die IL identisch sein. Wie andere bereits erwähnt haben, machen Sie sich keine Gedanken über solche Dinge, bis sie zu einem Problem werden. Fragen Sie sich stattdessen, wo der Gültigkeitsbereich der Variablen liegt.

Der Umfang und Kontext dieses Codeblocks ist viel wichtiger als kleine Leistungsoptimierungen, die in der Natur verfrüht und in diesem Szenario unnötig wären.

7

Dort ist ein Randfall, wo dies von Bedeutung ist; wenn Sie die Variable in eine anonyme Methode/Lambda "einfangen". Ansonsten ist es voreilig und macht keinen Unterschied. Überhaupt.

Ein Beispiel, wenn es keine Rolle spielt:

// 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); }); 
} 
Verwandte Themen