views:

250

answers:

8

What is better for performance wise declaring the variable outside the foreach statment and the each time reassign it in side it (foreach) or create an new variable inside foreach for example

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

or this one?

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

sure here I'm speak about item object. thank you all.

+4  A: 

I'm pretty sure the IL generated by your two code blocks is identical. There shouldn't be any change in performance. However the second code block where you declare the type of item right where it is used is slightly more readable and I would use that.

Praveen Angyan
+10  A: 

This sounds like a premature optimization.

First of all, do you have any reason to believe that there is a performance problem here?

Second, in release builds, the compiler's optimizer will probably produce identical code for both scenarios - so it's likely irrelevant. In debug builds this may not always be true, but there you don't want optimizations since the intent of debug builds is to allow you to accurately step through the code.

LBushkin
+3  A: 

This is a very-micro-optimization and both methods will likely be exactly the same performance-wise, if not generating identical code. In this case, go for readability. I'd prefer the second, since your object serves no purpose outside of the foreach loop.

Arguably, you could also get rid of the stored reference all together:

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;
}
Will Eddins
This is usually what I do. It is self serving, so I'll upvote you :D
Ty
A: 

Probably compiles to the same code but why bother redeclaring it. That is the nice thing about the reference, in this case item. Once you're done with it you can assign it to another ListItem and the GC takes care of the rest.

But on the otherhand readability for other programmers. It's a decision that certainly won't drastically change your applications performance.

JonH
A: 

Even better in your case is :

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

Why create an extra variable at all?

Charles Bretana
A: 

The IL created by the two blocks should be almost the same. If you are looking to optimize, I would look at setting the length of the final list before filling it with items. That way you won't be the expansion penalty for extending the length of the list.

Something like:

  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;
    }
Kevin
A: 

As everyone has speculated, the IL will be identical. Also, as others have mentioned, don't worry about things like this until they become a problem. Instead, ask yourself where the scope of that variable belongs.

The scope and context of that block of code is much more important than tiny performance optimizations that would be premature in nature and unnecessary in this scenario.

Ty
+2  A: 

There is an edge case where this matters; if you "capture" the variable into an anonymous method / lambda. Otherwise it is premature and makes no difference. At all.

An example of when it does matter:

// 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); });
}
Marc Gravell