Ahmed Magdy
Ahmed Magdy

Reputation: 6030

foreach, performance-wise. Should we declare variable once before loop or inside it?

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.

Upvotes: 6

Views: 1646

Answers (8)

Marc Gravell
Marc Gravell

Reputation: 1062865

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

Upvotes: 7

Ty.
Ty.

Reputation: 3948

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.

Upvotes: 0

kemiller2002
kemiller2002

Reputation: 115488

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

Upvotes: 1

Charles Bretana
Charles Bretana

Reputation: 146499

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?

Upvotes: 0

JonH
JonH

Reputation: 33153

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.

Upvotes: 0

Will Eddins
Will Eddins

Reputation: 13907

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

Upvotes: 3

LBushkin
LBushkin

Reputation: 131686

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.

Upvotes: 13

Praveen Angyan
Praveen Angyan

Reputation: 7265

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.

Upvotes: 4

Related Questions