Optimising coroutine yielding in C#

by AngryAnt on January 14th, 2010

When needing to yield a coroutine for a single frame in C#, most people – including myself usually go about it this way:

private IEnumerator DoFadeAlphaIn ()
{
    while (m_Alpha < 1.0f)
    {
        m_Alpha += Time.deltaTime;
        yield return 0;
    }
    m_Alpha = 1.0f;
}

However, as Rodrigo recently brought to my attention, this approach ofcourse performs unneeded memory allocation, given that the zero needs boxing and unboxing before its passed to the coroutine system. Using null in stead saves you that work and allocation.

This might not seem like a lot at first glance, but if you make this a habit every time you need to yield for a frame, I guarantee you that you’ll see results in larger scenarios.

The more optimal way of yielding for a single frame in C#. Minor difference, but allocation saved – which is always awesome:

private IEnumerator DoFadeAlphaIn ()
{
    while (m_Alpha < 1.0f)
    {
        m_Alpha += Time.deltaTime;
        yield return null;
    }
    m_Alpha = 1.0f;
}

An interesting test could be to, on a larger co-routine heavy project, do a project-wide find and replace on “yield return 0;” and “yield return null;” back and forth and measuring the performance difference with the profiler (for non-pro users, maybe the performance gain is even measurable using external monitoring tools).

9 Comments
  1. Ashkan permalink

    wow great! i always hate this zero but could not find a way to remove it. :)
    who is rodrigo? is he one of UT staff?

  2. Very helpful trick! I also noticed that yield generates a huge pause when switching (according to the profiler in 2.6) up to 15-20 ms and it results in the frame drop….

  3. @Ashkan
    Rodrigo works for Unity, yea. Resident .net specialist and test driven development advocate :)

    @TauPowered
    Yield will still generate overhead. This trick just removes some of it :)

  4. Thanks for the tip AngryAnt! On behalf of the community, I urge you to do more of these kinds of posts :) It helps a lot.

  5. Glad you found it useful :) Just because I joined the company, it doesn’t mean I left the community ;)

    I have no plan on stopping this new past-time, but I will be more busy at times and delays in postings will follow :)

  6. Nice!! Just replaced a lot of return 0’s on my code :-)

  7. Ashkan permalink

    i tested this with 5000 objects that they are simple spheres. i made 2 components that they have one coroutine with two lines of code.
    the FPS with return 0 is 200 but with return null is 230.
    this is the coroutine

    IEnumerator test2()
    {
    while (true)
    {
    transform.Translate(Random.Range (-30,30),0,0);
    yield return null;
    }
    }

    :) thank you :)

  8. Thanks for sharing your results :)

  9. gnoblin permalink

    Terrific!
    I’ve always used return 0… =В

Leave a Reply

Note: XHTML is allowed. Your email address will never be published.

Subscribe to this comment feed via RSS

Spam protection by WP Captcha-Free