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:
- Increased memory usage (building a
List
, separate from theIEnumerable
). Probably not that big of a deal, unless you do this very frequently, or theIEnumerable
is very large. - Decreased speed, since it has to go through the
IEnumerable
at once to build theList
. - 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.
精彩评论