Over a year ago I wrote an article title Do Foreach Loops Create Garbage using Unity 5.2 and tested foreach with a variety of collections: List, Dictionary, arrays, etc. Since then Unity has a new C# compiler and version 5.6 has been released. Is it safe to use foreach now? Read on to find out!

Today’s article is simply a re-test of the same exact test script from the previous article. Instead of Unity 5.2.2f1, I’ve tested today with 5.6.0f3. All of the code and steps to run it still apply.

As a reminder, the test script uses a foreach loop on a variety of collection types (e.g. List) to see if any garbage is created. It then runs another foreach loop to see if any garbage is created the second time, which may not be the case if there’s some internal caching going on.

Now on to the huge table of results. I’ve added a “5.2 Total” column on the right side to show the previous results.

Type GetEnumerator() MoveNext() Current Dispose() 5.6 Total 5.2 Total
1st 2nd 1st 2nd 1st 2nd 1st 2nd 1st 2nd 1st 2nd
Array n/a n/a n/a n/a n/a n/a n/a n/a 0 0 0 0
ArrayList 40 40 0 0 0 0 n/a n/a 40 40 40 40
BitArray 40 40 0 0 17 17 n/a n/a 57 57 57 57
Dictionary<T> 32 0 32 0 0 0 0 0 64 0 72 40
HashSet<T> 32 0 0 0 0 0 0 0 32 0 40 40
Hashtable 56 56 0 0 32 32 n/a n/a 88 88 88 88
IEnumerable 40 40 0 0 20 20 0 0 92 60 92 60
IEnumerable<T> 40 40 0 0 0 0 0 0 40 40 40 40
LinkedList<T> 32 0 0 0 0 0 0 0 32 0 48 48
List<T> 0 0 0 0 0 0 0 0 0 0 40 40
Queue 32 32 0 0 0 0 n/a n/a 32 32 32 32
Queue<T> 32 0 0 0 0 0 0 0 32 0 32 32
SortedDictionary<TKey, TValue> 32 0 256 192 0 0 0 0 288 192 304 240
SortedList 178 64 0 0 32 32 n/a n/a 210 96 210 96
Stack 32 32 0 0 0 0 n/a n/a 32 32 32 32
Stack<T> 32 0 0 0 0 0 0 0 32 0 32 32

Dictionary<T>, HashSet<T>, LinkedList<T>, Queue<T>, and Stack<T> now create the same, 8, or 16 bytes less garbage on the first loop and zero garbage on any loops thereafter. That’s great news because there’s no way to use a plain for loop instead of foreach with any of these collections.

SortedDictionary<TKey, TValue> now creates 16 bytes less garbage on the first loop and 64 bytes on subsequent loops. It’s still the biggest garbage creator of any collection, so try to avoid it if you’re keeping clear of the GC.

Finally the big news: List<T> no longer creates any garbage! This is by far the most common collection, so this is a huge win for us Unity programmers! Of course there is a caveat to that. In order for the foreach loop to not create any garbage, you need to use a List<T> variable. You can’t use an interface that it implements like IEnumerable<T> or 40 bytes of garbage will be created every loop. Normally you can avoid that though, and you should if you want to take advantage of a garbage-free foreach.

While all the other collection types haven’t changed the amount of garbage they create, at least none of them use more garbage than they did back in Unity 5.2. So we have nothing but good news today. If you’re using foreach because you can’t use for then you’re not going to be creating as much garbage as before with common collections like Dictionary<T>. With List<T> you won’t be creating any garbage, so there’s no need to use for with them anymore.