- Home /
Is Using Coroutines Actually Faster Than Update?
I've been doing a lot of research lately on how to increase performance of games on mobile and one piece of advice I came across was to use coroutines in place of Unity's built in Update function. It was mentioned on the forums that Update works closer to SendMessage than a standard function call, which causes more of an overhead. I'm very far into my project at this point so I wanted to get some data on the performance difference between Update and coroutines before overhauling my entire project. I created a blank project that has 1000 empty game objects running a simple update and 1000 empty game objects running the operation as a coroutine. The results were overwhelmingly in favor of Update, much to my surprise. Below are the two scripts used to test. Also attached below are the results of the profiler running on an original Motorola Droid. (It is worthwhile to note that this same project was tested on an iPhone 4 with almost identical results).
My best guess is the fact that System.Collections.Generic is not native to Android or iOS so Unity has to include it, which creates an overhead. Does anyone have any ideas why coroutines would be so much slower than Update?
Update:
private int count;
private float sine;
// Update is called once per frame
void Update ()
{
count++;
sine = Mathf.Sin(count / 0.2F);
}
Coroutine:
private int count;
private float sine;
// Use this for initialization
void Start ()
{
StartCoroutine(AddCount());
}
private IEnumerator AddCount()
{
while (true)
{
count++;
sine = Mathf.Sin(count / 0.2F);
yield return null;
}
}
great test, would like to see some more! I was wondering if you could test this with the exact same code in both Update and the coroutine, the reason being, i wonder if the check on the while loop within the coroutine would slow it down and be an unfair test?
Coroutines are not "functions". They work completely different. All your code is packed into a statemachine like construct and is hidden in the IEnumerators $$anonymous$$oveNext method. If you enable deep profiling you see calls to subroutines.
@Ceraph: $$anonymous$$ay i ask what android device you use for profiling / debugging? Since the last Android update (Jelly bean 4.3) all Unity development builds crash on startup.
@Bunny83 Thanks for the clarification, I will try and adapt this test to use the event dispatch method. This was tested on an original $$anonymous$$otorola Droid running Android 2.2.3. I also tested it on an iPhone 4 with iOS 6 with similar results but the screencaps above are from the Android test.
@Lando1000 The while loop is there to ensure the coroutine runs every frame, otherwise it would run once on startup and stop.
@Ceraph I'm aware of that but because its within a loop i was wondering if the check "while(true)" was causing a slight time increase but from reading the other posts it might be irrelevant
Answer by Bunny83 · Aug 29, 2013 at 07:46 AM
Of course 1000 coroutines will be more expensive than 1000 Updates. Coroutines are objects which are managed by the coroutine scheduler of Unity. What might be more efficient is to have one dispatcher object with one Update function or a coroutine and dispatch an event to an array / List of objects directly. This of course requires each script to provide a common interface.
Either use, well, and interface or a baseclass with a method that can be overridden in a subclass. The interface approach is more flexible, whereas the basclass approach allows drag and drop in the inspector.
If you "subscribe" your object via script at runtime i would go with an interface.