Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

performance of yield return new WaitForSeconds(0.1f)

Discussion in 'Scripting' started by jayanthg, Jun 29, 2016.

  1. jayanthg

    jayanthg

    Joined:
    May 26, 2013
    Posts:
    48
    Hi All,

    Generally when we need to yield from a coroutine for a specific time interval, all the examples I have seen till date write,

    while (true)
    {
    yield return new WaitForSeconds(timeToWait);
    }


    if timeToWait is real small, aren't we creating too many YieldInstructions?

    Is it better to write:

    YieldInstruction yi=newWaitForSeconds(timeToWait);
    while (true) {
    yield return yi;
    }

    Are there any caveats like the yield instruction is mutable and should not be reused?
     
  2. jimroberts

    jimroberts

    Joined:
    Sep 4, 2014
    Posts:
    560
    It's better not to use co-routines at all. Instead use the Time class to implement a simple timer in Update or even FixedUpdate.

    PseudoCode:
    Code (CSharp):
    1. public float Next;
    2. public float TimeToWait;
    3.  
    4. void Update()
    5. {
    6.     if (Time.time >= Next)
    7.     {
    8.         Next = Time.time + TimeToWait;
    9.  
    10.         //doSomething
    11.     }
    12. }
     
    MikeTeavee likes this.
  3. MikeTeavee

    MikeTeavee

    Joined:
    May 22, 2015
    Posts:
    194
    As far as I know, yield-return and a regular return are the same performance-wise, so dont worry about multiple calls.

    On the other hand, when you implement data structures into coroutines, you need to be extra careful. (memory concerns)
     
    Last edited: Jun 29, 2016
  4. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,422
    Yes you are better to not create a new instance each iteration.

    There is no issue doing this - it is designed to be reused in this manner, it's the norm.

    With regards to using Update() logic as jim showed - IMO, any performance gained doing so is well out weighed by added complexity. Do what's the most simple and care about performance when the profiler says you should.
     
    Last edited: Jun 29, 2016
    jayanthg and Kiwasi like this.
  5. jayanthg

    jayanthg

    Joined:
    May 26, 2013
    Posts:
    48
    Thanks Guys. But I want to use a coroutine because:

    1. Its better to suspend the code instead of "busy waiting"
    2. Keep the code organised.

    I am not worried about performance of "return". I am worried about the repeated memory allocation using "new".

    So, repeating my question, is it ok to use the same instance of YieldInstruction repeatedly?

    EDIT: Thanks larku, i guess we posted at the same time. Will go ahead.
     
    larku likes this.
  6. jimroberts

    jimroberts

    Joined:
    Sep 4, 2014
    Posts:
    560
    ...What added complexity? It's literally doing the exact same thing as a co-routine without the pointless overhead. Just disable or delete the component if you want to suspend or stop the loop. If your component is implementing multiple behaviours then you're doing something horribly wrong.
     
  7. sngdan

    sngdan

    Joined:
    Feb 7, 2014
    Posts:
    1,131
    there is a free asset (i think 'memory efficient coroutines') i would check in your case, i think also lot's of forum discussion to understand performance, etc.

    back to your point, I think your approach is perfectly fine, requires just a bit of organization
    • if you have specific wait times, you could define them all as global variables / constants.
    • like this: WaitFor2Seconds = new WaitForSeconds (2f);
    • in the Coroutine, you would not need a while loop, just call yield return WaitFor2Seconds
     
  8. larku

    larku

    Joined:
    Mar 14, 2013
    Posts:
    1,422
    I didn't mean that in any negative way. But every bit of added complexity adds up over time when considering maintenance, debugging, etc.

    IMO, the co-routine approach is self explanatory and easy to follow for the 'non author' (maintenance) or when you return to the code after some time.

    It's the same rationale why I always suggest using LeanTween (or similar) to do lerping/tweening/moving/scaling/etc from code - sure you can do it in an update loop - but eh, it's horrible to read in comparison.

    IME coroutines have never been a cause of performance issues in anything I've written - there's sure to be cases, but they're not the norm.

    There's no question that the Update() method has more complexity (2 member variables, an assignment, addition and comparison - all in a scope different to where the event was initiated)..

    I'm talking complexity for the programmer - not the compiler, runtime or anything similar.
     
    jayanthg likes this.
  9. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    YieldInstructions do get GC'd. So if you are tight on garbage, reusing the same instruction will help. Thinking about it I'm not sure why Unity choose to use a class instead of a struct. A struct would probably be better for this job.

    The constant timer checking in Update is fine if you need to do something every frame, or if it's always on. But it doesn't make a whole lot of sense otherwise.
     
  10. jayanthg

    jayanthg

    Joined:
    May 26, 2013
    Posts:
    48
    Its a class instead of a struct because it has to implement IEnumerator.
    Not sure of the inner details though.
     
  11. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Figured there was something I was missing.

    Then again, if they were to rebuild coroutines from scratch it would probably be different. Looking forward to the day when generic coroutines and custom yeild instructions are implemented.
     
  12. orb

    orb

    Joined:
    Nov 24, 2010
    Posts:
    3,033
    jayanthg likes this.
  13. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,199
    What do you mean by custom yield instructions? Something like CustomYieldInstruction?

    :D
     
    Kiwasi, larku and orb like this.
  14. TJHeuvel-net

    TJHeuvel-net

    Joined:
    Jul 31, 2012
    Posts:
    818
    Have you seen this pop up in your profiler somewhere? Otherwise, dont worry about it.
     
    larku and orb like this.
  15. jayanthg

    jayanthg

    Joined:
    May 26, 2013
    Posts:
    48
    Woah! Lovely! For all those who are depending on the profiler, please remember it can help you only to some extent. It cannot catch all mistakes, like this one.

    Now going through my entire code!
     
  16. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Got to start paying attention to release notes...
     
  17. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,146
    https://www.assetstore.unity3d.com/en/#!/content/54975

    The asset you speak of. I have yet to try it out, but I was curious how well it improved coroutines.