Search Unity

Coroutine take extremely long time for simply calculation

Discussion in 'Scripting' started by Pontik, Nov 27, 2016.

  1. Pontik

    Pontik

    Joined:
    Feb 26, 2014
    Posts:
    17
    Hello community,
    i have created here some code for a simply test for something like a asynchron calculation. But i was realy surprised to see how much time a coroutine take to count to 1000? Nearly 17 seconds?! A simply while lop will take much fewer as 1ms for that. May be i do something wrong because i can not belive it is normal time for this operation.

    Here is my code:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Linq;
    3. using System.Diagnostics;
    4. using System.Collections;
    5.  
    6. public class UnitTest : MonoBehaviour {
    7.     delegate void OnCalculationResult(int result);
    8.     void Start()
    9.     {
    10.         DoSomeStuff();
    11.     }
    12.  
    13.     private void DoSomeStuff()
    14.     {
    15.         print("I do some stuff");
    16.         //Calculate(100, HandleResult);
    17.         StartCoroutine(Calculate(HandleResult));
    18.         print("I do some another stuff [1]");
    19.         print("I do some another stuff [2]");
    20.         print("I do some another stuff [3]");
    21.         print("I do some another stuff [x]");
    22.     }
    23.  
    24.     private void HandleResult(int result)
    25.     {
    26.         print("Calculation result handled: " + result.ToString());
    27.     }
    28.     private IEnumerator Calculate(OnCalculationResult ResultHandleFunction)
    29.     {
    30.         Stopwatch watch = System.Diagnostics.Stopwatch.StartNew();
    31.  
    32.         var initValue = 0;
    33.         while (initValue < 1000)
    34.         {
    35.             initValue++;
    36.             yield return null;
    37.         }
    38.         watch.Stop();
    39.         print("MyCoroutine is now finished in: " + watch.ElapsedMilliseconds.ToString() + " ms.");
    40.         ResultHandleFunction(initValue);
    41.     }
    42. }
    The result is: http://shot.qip.ru/00NDav-2oHGounG8/
     
  2. L-Tyrosine

    L-Tyrosine

    Joined:
    Apr 27, 2011
    Posts:
    305
    Coroutines does not process things asynchronous (like a thread would do), they just span the process over frames (or time if you use WaitForSeconds).

    In your case, each iteration has to wait 1 frame
    Code (csharp):
    1.  
    2. yield return null;
    3.  
    So this time that you see it is the time that 1000 frames take in your game.
     
    Pontik likes this.
  3. Pontik

    Pontik

    Joined:
    Feb 26, 2014
    Posts:
    17
    Oh, now i see! Thank you. Now it make sense for me!
     
  4. ericbegue

    ericbegue

    Joined:
    May 31, 2013
    Posts:
    1,353
    coroutine != thread
     
  5. Pontik

    Pontik

    Joined:
    Feb 26, 2014
    Posts:
    17
    coroutine != thread

    yes, i understand. The sense of this test was not to make a real asyncronous operation, but the code should go further and not wait for calculation end. My keyword asynchron is wrong in this case, i know.
     
  6. Pontik

    Pontik

    Joined:
    Feb 26, 2014
    Posts:
    17
    My mistake was to put yield method inside the while loop. It should be on the first line inside Calculate IEnumerator. In this case it return one time wait for 1 frame and the code below will execute "callback" after it is completed. In this time the parent function where i started my coroutine can go further without waiting for a result.
     
    Last edited: Nov 27, 2016