Do we still need to avoid foreach loops?
While searching for a solution to a bug in my game I ran across this page saying that foreach
loops are buggy and shouldn't be used. However, this post is a couple of years old. Does anybody know if this bug still exists?
Additionally, will the unityscript's for (var in container)
syntax have the same problems since they compile to the same bytecode?
Answer by pako · Aug 28, 2015 at 10:37 AM
I read the forum thread in your link, and I think the juice in this issue is that:
Unity uses and old version of Mono
This old version of Mono boxes structs collections, and boxing/unboxing is a "heavy" operation
Therefore, if you don't use struct collections, this issue does not apply. And if you use struct collections minimally, and infrequently, the impact on performance will be minimal and most probably unnoticeable.
A mono upgrade in Unity has not happened yet, and will not happen until IL2CPP is mature and used on all required platforms:
http://answers.unity3d.com/questions/924021/what-is-the-version-of-net-in-unity-5.html
https://www.reddit.com/r/Unity3D/comments/2e4q6c/unity_upgrading_to_c_5_and_net_45/
Here is a link to Unity Roadmap, if you want to follow the developments:
Answer by mikelortega · Aug 28, 2015 at 08:44 AM
The way the compiler handles iterators in foreach
loops generates unnecessary memory allocations. Remember you should reduce memory allocations to minimize the Garbage Collector load. It usually won't be a problem when you use foreach
to do initializations, but it may allocate too much memory when called constantly (every frame).
I think you will have the same problem with UnityScript's for (var in container)
I recommend you to check the GC Alloc column in the Profiler. It will tell you when allocations are made in your foreach loops.
The memory allocations are due to a bug in the old version of $$anonymous$$ono that Unity is still using, not because of unrolling loops. See @Pako's answer.
Answer by andrew-fray · Jul 31, 2017 at 01:28 PM
They upgrade the mono compiler (but not the runtime) in 5.5 (https://blogs.unity3d.com/2016/11/29/unity-5-5-is-ready-for-you/) and that means foreach is much better, including being 0-alloc for Lists: http://jacksondunstan.com/articles/3805