Why?!!! Are you just trying to make it difficult on yourself?!
One unit of CPU work done in Update() costs PRECISELY the same amount as if it is done anywhere else.
The reason: from the C# scripting perspective, Unity is single-threaded. No really, go back and read that again. SINGLE threaded. One thing must complete executing before the next can happen, and ALL the things must complete before the next frame is rendered.
If you doubt me, here is some timing diagram help:
https://docs.unity3d.com/Manual/ExecutionOrder.html
Note how ALL the Update()s are called, THEN the coroutines are processed. Every single frame.
I don’t know exactly where this fetish for “get it out of the Update()” loop began but it leads to horrible code. If you check something every frame in a coroutine, that is exactly as expensive as putting it in Update(), but now you have confused your code if a coroutine doesn’t actually model what you’re trying to do.
If something is appropriately “fired off and forgotten,” then maybe it belongs in a coroutine. Nothing ever MUST be in a coroutine, and there is rarely any performance benefit to it.
You can still use coroutines anywhere you like. It’s up to you. Somebody has to “run” them. Bare classes cannot run coroutines, but they can certainly hand back IEnumerators, which other things can “run,” things like MonoBehaviors.
But if you prefer, you can take an IEnumerator and “pump” it yourself periodically by calling .MoveNext(). That’s all a MonoBehavior does, nothing more, nothing less. That’s why you don’t get any magical benefit because you stuck something in a coroutine. It is still executed by precisely the same CPU thread as if it were in Update(). Honest!
Coroutines in a nutshell:
https://discussions.unity.com/t/825667/6
https://discussions.unity.com/t/749264/9