I just started studying Unity scripting and I'm having a hard time to understand why some people prefer coroutines over state machines.
I do understand that the code might be more readable for some programmers, but I can't understand why some people say that using coroutines are preferable for performance.
I'm using C# in Unity, and from what I understand the C# compiler converts the IEnumerator into a state machine.
So maybe I'm missing something here. Is it better for runtime performance to use Coroutines instead of a FSM loop for handling behavior and states? If yes, why?
Using coroutines is faster in some circumstances because you can conveniently schedule Unity to perform operations at certain intervals rather than doing them every frame, thus saving processing time. It's really the scheduling that saves time, not coroutines as such.
Take the example you highlighted (in you comment in the other answer) from the Unity documentation, where it says:
Use Coroutines. The problem with Update calls is that they happen every frame. Quite possibly checking the distance to the player could be performed only every 5 seconds. This would save a lot of processing power.
This is saying that a coroutine that uses WaitForSeconds( 5f ) will be faster then checking the distance every frame. It doesn't mean that doing so would necessarily be faster than having your own Update logic that only checks distance every five seconds.
Having said that, I wouldn't be surprised if the coroutine approach is still faster (though less dramatically so) than Update-based checking-every-five-seconds logic, because you'd still save on checking the current frame's time every frame in your game code. Yes, somewhere in Unity's engine loop this time check is still happening and being used to determine whether to go to the next coroutine step, but it's likely highly optimized and it's happening anyways, so the coroutine isn't adding as much extra time checking logic as the Update-based approach.
By the way, for a nice outline of how Unity is likely implementing coroutines, see this blog post.
You have to be careful about what you're using coroutines for. They are great for long-running operations that you don't want to hang the game.
However you have to be very careful about how often you yield in the coroutine. Every time you yield, it takes some time (multiple frames) for the coroutine to resume. If you yield too much, your coroutine will be processing slower than it needs to be. For example, I was working on a pathfinding system. I was using a coroutine to periodically yield while it was running the pathfinding algorithm. This was causing the pathfinding code to take much longer than it should have. I found it worked much faster to just do it in Update.
Coroutines are nice for doing long-running asynchronous tasks like a web request, or downloading something in the background, etc. I don't know that I would recommend using coroutines for your main game processing loop. (especially for input)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With