Should I read variables serveral times, or store as temporary variable?

Hey folks,

this is not a specific Unity question, but maybe interesting (or not) for game development in general.
I was wondering if it makes a difference if I try to read a variable directly several times in a single update loop, or if it would be better (performance and memory) to save the variable temporary (see Example 1, Example 2 and Example 3 below).

On the one hand we can consider that a stored variable needs virtual memory of the random access memory (RAM). On the other hand it needs performance of the graphic card or rather the processor (core) to read a variable.

Maybe some questions a pro or person with knowledge and/or experience can answer:

  1. Is there a difference in performance and memory?

  2. If yes, how can we observe the impact?

  3. Is there a break even point, when it makes sense to use the one solution or the other?

  4. Whats better to read and debug?

    using UnityEngine;
    
    public class Excample : MonoBehaviour
    {
        private Animator animator;
        private float tmpFloat;
        private float animatorFloatValue;
    
        // Update is called once per frame
        void Update()
        {
            //Example 1: (float reads: 1, float saves: 2)
            tmpFloat = animator.GetFloat("My Animator Float");
            animatorFloatValue = tmpFloat * tmpFloat;
            animator.SetFloat("My Animator Float", animatorFloatValue);
    
            //Example 2: (float reads: 2, float saves: 1)
            animatorFloatValue = animator.GetFloat("My Animator Float") * animator.GetFloat("My Animator Float");
            animator.SetFloat("My Animator Float", animatorFloatValue);
    
            //Example 3: (float reads: 3, float saves: 0)
            animator.SetFloat("My Animator Float", animator.GetFloat("My Animator Float") * animator.GetFloat("My Animator Float"));
        }
    }
    

Hey there,

First as a general rule for optimization: Do not waste time on it if you do not really know if that even has any significant impact.

That being said lets tackle that case of yours.
If you really want to understand the ins and outs of all this then you should start handling memory usage not just as “allocated RAM” but differentiate between Stack and Heap allocations.
Short version: Stack good and fast, Heap bad and slow.

Afaik any reference object (so any class instance) will be on the heap and create GC.alloc calls which are visible in the profiler. Local value type variables will be on the stack. With this in mind lets look at function regarding memory.

None of the example cases of yours creates a new variable as all values are already member variables of the class itself. Given this the “float saves” comments you added are a bit misleading imo. As long as GetFloat and SetFloat do not allocate memory somewhere below the hood then there is no memory allocation taking place here.

But even if you had

         var animValue = animator.GetFloat("My Animator Float");
         var animValuePow2 = animValue * animValue;
         animator.SetFloat("My Animator Float", animValuePow2);

There would be no “bad” memory allocations as bot animValue and animValuePow2 would be created on the Stack which in itself is fast and ok. An improvement here would be:

         var animValue = animator.GetFloat("My Animator Float");
         animValue = animValue * animValue;
         animator.SetFloat("My Animator Float", animValue );

As you just reuse the old memory. Do not optimize your code for this. This is a waste of time undless you want to do these calculations millions of times per Frame

Now regarding general speed, to measure that you mostly try to execute your code like 1000000 Times and check how long it takes. Then you have an average on how long one execution takes and thus can compare your different versions. Use the profiler to get a general idea about what is slow or fast here!

As a rule of thumb from my Unity Experience: GetFloat and SetFloat will be slow. Same for functions like GetComponent or all FindObject.... functions. Try to use those as little as possible and always cache the result in a variable. That being said my guess would be that Example 1 in your code should be by far the fastest.

For point4: That sometimes can be a subjective question/answer but imo Example 1 is the objectively best here. Mostly because the code in its current version has the least appearances of "My Animator Float" which you’d have to change everywhere in your code if you wanted to change the variable name in the animator. Regarding this i can only heavily recommend to use member variables in your class for these things as it reduces the possibility for errors. So i’d write this piece of code like this:

  private readonly string ANIMATOR_FLOAT_NAME = "My Animator Float";

     void Update()
     {
         var tmpFloat = animator.GetFloat(ANIMATOR_FLOAT_NAME );
         tmpFloat = tmpFloat * tmpFloat;
         animator.SetFloat(ANIMATOR_FLOAT_NAME , tmpFloat );
      }

Hope this helps, let me know what you think.