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. Dismiss Notice

Question Performance question: the cost of the cooldown.

Discussion in 'Visual Scripting' started by Marou1, Jun 27, 2023.

  1. Marou1

    Marou1

    Joined:
    Dec 13, 2021
    Posts:
    141
    Hello,
    In order to enhance the performance of UVS (one of its weakest points), I am adding Cooldowns before some OnUpdates so the whole calculation is not performed on each frame. When the calculation is complex, it seems obvious that the Cooldown on every 0.1 second for example is better. But in some cases, I am not sure because I don't know what is the cost of the cooldown.
    upload_2023-6-27_11-1-49.png
    Intuitively, I'd say... low...?
    But with UVS there may surprizes, so I prefer to ask.

    Thanks!
     
  2. PanthenEye

    PanthenEye

    Joined:
    Oct 14, 2013
    Posts:
    1,754
    Cooldown has a built in coroutine which allocates, I assume when cooldown restarts a new coroutine is created with new allocations. Hard to gauge the benefit without profiling. You could create a test scene which spawns X amount of rotating cubes with just update, and then the same amount cubes with cooldown and see what the Profiler says for each set of cubes.

    EDIT: Also, doesn't OnUpdate reset the Cooldown since it refreshes every frame?
     
  3. Marou1

    Marou1

    Joined:
    Dec 13, 2021
    Posts:
    141
    I am not sure I understand what you mean. The second input of the Cooldown is the Reset, if nothing is connected to it, it won't be reset.
    I connect the OnUpdate to the first input of the Cooldown, and the Cooldown fires every X seconds. So it works well.

    If not using the cooldown, what would be the option to check something every X seconds, instead of every frame?
     
  4. PanthenEye

    PanthenEye

    Joined:
    Oct 14, 2013
    Posts:
    1,754
    Ah, I wasn't aware of cooldown gating OnUpdate flow. Cooldown is probably fine, but OnUpdate in VS is expensive since it tries to process the flow every frame. You could start the Cooldown with OnStart, then reset the cooldown with a custom event. It would still do something every X seconds without OnUpdate processing every frame.

    Alternate way of achieving this would be OnStart marked as coroutine + While Loop + Sequence node, where first sequence output is your logic and second output is Wait for Seconds node. This approach lets you optionally stop the logic entirely and restart it with a custom event whenever.

    EDIT: From my limited tests, this seemed to be more performant than the usage of Cooldown node in a scenario where I instantiate 100 rotating cubes in a grid.


    But both Cooldown and Start marked as coroutine allocate memory for couroutines and that GC has to be collected sometime which can lead to a lag spike. Pure OnUpdate() doesn't allocate any memory so there's no GC to collect and no lag spike. So this is very case by case dependent. There's no general rule. And perhaps Cooldown comes ahead of the above solution when the flow is very logic heavy since Start marked as Coroutine includes all following logic as part of that coroutine while Cooldown is more encapsulated.
     
    Last edited: Jun 29, 2023
  5. Marou1

    Marou1

    Joined:
    Dec 13, 2021
    Posts:
    141
    Ok... I am kind of surprized that OnUpdate costs more than a while loop + a wait. But in the meantime, a few months ago, I tested a script with a lot of OnUpdates not doing anything and a script was killing the performance. I doubted my findings thinking I was missing something, but you are actually confirming them.
    Both your suggestions are smart. Thanks!
     
  6. PanthenEye

    PanthenEye

    Joined:
    Oct 14, 2013
    Posts:
    1,754
    It depends, OnUpdate() is still faster for simple things since it doesn't allocate any memory for the coroutine. EDIT: But While loop was a bit more stable than Cooldown usage in my limited testing.
     
  7. PanthenEye

    PanthenEye

    Joined:
    Oct 14, 2013
    Posts:
    1,754
    When I ramped up the instance count of cubes, pure OnUpdate is about twice as fast as the While loop with 0.1s delay, and Cooldown also with 0.1s timer is somewhere in the middle between While loop and OnUpdate.
     
  8. Marou1

    Marou1

    Joined:
    Dec 13, 2021
    Posts:
    141
    So you are saying that OnUpdate is the fastest?
    I am no sure to understand the test you did
    Thanks!
     
  9. PanthenEye

    PanthenEye

    Joined:
    Oct 14, 2013
    Posts:
    1,754
    For basic operations, OnUpdate is faster.

    In a new project I spawned rotating cubes in a grid with this graph. Then swapped out the prefab for each type of cube for repeat tests. Then simply look in the profiler at PlayerLoop - how much ms it takes compared to other cubes.


    Prefab for each cube type:

    DoWhile (slowest):

    StartCooldown and UpdateCooldown (faster than DoWhile, slower than pure OnUpdate). Didn't see much difference between OnUpdate and OnStart but OnStart would be a safer bet.




    OnUpdate(best performance for simple operations):



    For simple operations that happen every frame, adding a coroutine delay with Cooldown or DoWhile doesn't seem to net any benefit in this test case scenario. There might be a benefit for heavy operations i.e. large flows that do way more than just cube rotation but this is very case by case dependent on what you're doing. There is no universal answer. You have to profile your game so you can determine performance bottlenecks, then optimize those.
     
    Last edited: Jul 4, 2023
  10. Marou1

    Marou1

    Joined:
    Dec 13, 2021
    Posts:
    141
    I know, but there is sooo much to do... :) For now I am doing regularly a high level profiling, launching a building and checking the CPU and GPU. In my case, it's the GPU that is the bottleneck (!). So I'll have to look at this first. The CPU is ok so far. But I try to choose the most efficient way to program my stuff from the beginning so the optimization phase will cost less.
    Anyway, thanks for doing these tests, it is insightful!