开发者

Is garbage created in this foreach loop?

I came across a method to change a list in a foreach loop by converting to开发者_如何转开发 a list in itself like this:

foreach (var item in myList.ToList())
{
     //add or remove items from myList
}

(If you attempt to modify myList directly an error is thrown since the enumerator basically locks it)

This works because it's not the original myList that's being modified. My question is, does this method create garbage when the loop is over (namely from the List that's returned from the ToList method? For small loops, would it be preferable to using a for loop to avoid the creation of garbage?


The second list is going to be garbage, there will be garbage for an enumerator that is used in building the second list, and add in the enumerator that the foreach would spawn, which you would have had with or without the second list.

Should you switch to a for? Maybe, if you can point to this region of code being a true performance bottleneck. Otherwise, code for simplicity and maintainability.


Yes. ToList() would create another list that would need to be garbage collected.


That's an interesting technique which I will keep in mind for the future! (I can't believe I've never thought of that!)

Anyway, yes, the list that you are building doesn't magically unallocate itself. The possible performance problems with this technique are:

  1. Increased memory usage (building a List, separate from the IEnumerable). Probably not that big of a deal, unless you do this very frequently, or the IEnumerable is very large.
  2. Decreased speed, since it has to go through the IEnumerable at once to build the List.
  3. Also, if enumerating the IEnumerable has side effects, they will all be triggered by this process.

Unless this is actually inside an inner loop, or you're working with very large data sets, you can probably do this without any problems.


Yes, the ToList() method creates "garbage". I would just indexing.

for (int i = MyList.Count - 1; 0 <= i; --i)
{
    var item = MyList[i];
    //add or remove items from myList
}


It's non-deterministic. But the reference created from the call ToList() will be GCd eventually.

I wouldn't worry about it too much, since all it would be holding at most would be references or small value types.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜