I recently started looking at performance optimization applicable in Unity. Doing Google searches showed out-of-date tests (much like this could be if you are reading in the far future).
I’m specifically trying to determine which type of loop (For Vs. ForEach) is the most efficient to use as 1) referencing GameObjects and 2) modifying a value.
For these tests I’m using Unity 2020.3.19f1 LTS on Windows 10 with an i9-10850 CPU with 16GB RAM. For updating values, the GameObject position was changed. I ran the test seven times and used the average to come to a conclusion. This is more as a reference rather than the “be all and end all” of which case suits your best. Basically, do your own tests to see how each case would suit your own needs.
Without further ado, here is are my test results iterating an array of 100,000 GameObjects:
|IL2CPP Editor||Read Value||Set Value|
|IL2CPP Player||Read Value||Set Value|
First off, Unity Editor has a lot of overhead and is going to be always much slower than a build. Testing in Unity Editor will help determine if there are easy performance gains. When you want to get more realistic values you need the Player build used by players.
Comparing Timings between the Editor and Player build when reading elements in an array
Comparing the Editor to the Player build, and reading values from an array timings move from the 100ths into the 1000ths of a second. Setting values is much slower than reading values measured in 10ths. Modifying elements in a list has a performance cost, so don’t update elements needlessly (much like you shouldn’t in any kind of game loop, i.e. Unity’s Update()).
Reading elements in an array
Does it significantly matter if you are using a For or ForEach loop when reading elements in an array? We are talking 10,000ths of a second. Not a significant difference between the two. If you want the fastest iteration possible then ForEach wins when reading elements in an array.
Comparing Timings between the Editor and Player build when writing elements in an array
Modifying a GameObject value has its performance cost (probably more due to using the position Vector3 array which is a struct) and the difference is 2/100ths of a second, and significantly more costly than just reading values.
Writing elements in an array
ForEach is 15/100th faster than For. This difference is not going enough to worry about on its own but ForEach is faster and the best choice for getting as much performance as you can.
A last-minute thought, quite literally, any garbage collection from using a For or ForEach. Several years back ForEach generated garbage, then an update improved its performance. This experiment has not taken this into consideration and could make a considerable difference in how much Garbage is generated and thus make Garbage collection run more frequently, slowing performance and increasing frame hitches.
Testing on a variety of target machines could impact performance differently.
Using Mono scripting backend could impact performance differently.
TL;DR: ForEach was faster than For in this experiment. That alone should not influence any decision-making process.
Garbage collection was skewing the results. The first time you access the .transform for a GameObject Unity generates garbage.
I got around this by just doing an initial iteration before testing the times. From some initial testing ‘For’ won 4 out of 7 times in the 1/100th’s of seconds.
Based on this there is not much potential for performance gains. It’s best to choose for or foreach based on the needs of the project.
This garbage generation on first time accessing the transform may be worth noting for anyone who pools gameobjects.