A lot of update call performance test results, why unity not using array?

Test case: 1000 GameObject with 10 components on each, so total of 10.000 update calls

With update manager: 0.3ms - 0.4ms

Without update manager: 4.4-5.2ms

With update manager checking if gameobject is active before ticking (which doesnt make sense to check like this, but still i wanted to test )

        for (int i = 0; i < _tickables.Length; i++) {
            if (_tickables[i].gameObject.activeSelf == false) continue;
            _tickables[i].Tick();
        }

But even this around 1.5 to 1.7ms

And last test with coroutine 10.2 / 10.4ms so this is the slowest

using System.Collections;
using UnityEngine;

public class MonoWithCoroutineUpdate : MonoBehaviour {
    IEnumerator Start() {
        while (true) {
            {
                Tick();
                yield return null;
            }
        }
    }

    void Tick() {
        
    }
}

Test code

using System.Collections.Generic;
using UnityEngine;

public sealed class Spawner : MonoBehaviour {
    [SerializeField] int spawnCount = 200;
    [SerializeField] GameObject prefab;


    MonoWithListUpdate[] _tickables;

    void Start() {
        var list = new List<MonoWithListUpdate>();
        for (var i = 0; i < spawnCount; i++) {
            var instance = Instantiate(prefab);
            list.AddRange(instance.GetComponents<MonoWithListUpdate>());
        }

        _tickables = list.ToArray();
    }

    void Update() {
        for (int i = 0; i < _tickables.Length; i++) {
            _tickables[i].Tick();
        }
    }
}
public class MonoWithUpdate : MonoBehaviour
{
    int i = 0;
    
    void Update()
    {

    }
}
public class MonoWithListUpdate : MonoBehaviour {

    public void Tick() {
        
    }
}

So updatemanager is far way more performant then writing update inside classes.

Im not the first who is making this test also other tests showed similar result.

So i wonder why unitys way is slow and why they dont fix it. Why they dont use array loop like in my example what is the reason can somebody explain me please, thank you

1 Like
  1. Yes, these findings are correct, and manually calling methods on multiple updates has been recommended for performance in a while
  2. Coroutines will always be slowest, async could be a performant alternative
  3. ‘Regular’ Update is slower because it is invoked. This because not every script or object has an Update. It can have multiple, none, added or removed at runtime. If you have 1 huge list which has to be refilled with all scripts and then check if it contains Update every frame, that’s gonna be intense. For smaller systems just make it yourself with a manager, or a flexible way using Events, is usually nice
1 Like

There’s a Unity blog on this exactly: 10000 Update() calls

It does a lot of stuff so there’s a lot of overhead.

3 Likes

Unity was heavily influenced by the Quake Engine which was designed for making a game with a few hundred entities at most. And around that time developers were becoming increasingly attracted to object orientated programming (OOPS). So Unity’s Update is basically a version of Quake’s nextthink method.

CPUs now have SIMD and vector processing which aren’t suited to OOPS and so there’s a shift back to the old ways of programming using simple arrays. Now whether it’s possible to make a sophisticated game by iterating over arrays of entities remains to be seen.

So to answer your question - Unity Tech’s fix is DOTS and ECS.

1 Like

Thank you all, thanks to your comments and this text from the unityblog mentioned, i understood now.

1 Like

What, you’re not even using the fastest way to loop!? :astonished:

2 Likes

Oh I didn’t know these differences :sweat_smile:, it was a useful video, thank you.

1 Like