Search Unity

Is there a benefit in caching a transform's rotation?

Discussion in 'Scripting' started by ArachnidAnimal, Jun 21, 2015.

  1. ArachnidAnimal

    ArachnidAnimal

    Joined:
    Mar 3, 2015
    Posts:
    1,815
    I've read that caching a GameObject's transform helps with optimization:

    Code (csharp):
    1.  
    2. public Transform _transform;
    3.  
    4. public void Start()
    5. {
    6. _transform = gameObject.transform;
    7. }
    8.  
    But, is it also efficient to cache the transform's rotation?
    Code (csharp):
    1.  
    2. public Transform _transform;
    3. public Quaternion _q;
    4.  
    5. public void Start()
    6. {
    7. _transform = gameObject.transform;
    8. _q = gameObject.transform.rotation;
    9. }
    10.  
    Thanks.
     
  2. LeftyRighty

    LeftyRighty

    Joined:
    Nov 2, 2012
    Posts:
    5,148
    not really, since the rotation is going to change. What you've done is store the initial rotation of the object.

    The point about caching the transform is that it points to a single, non changeable entity which you then don't have to look up every time you want to interact with it.
     
    NomadKing and ArachnidAnimal like this.
  3. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
    You no longer have to cache the Transform component, Unity does it for you automatically.
     
  4. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Unity doesn't cache the Transform component. Using the transform shortcut is faster than using GetComponent, but not as fast as caching it. As for the question, no, that's bad practice unless you need to store the initial rotation for some reason, in which case you should use a descriptive variable name such as "initialStoredRotation".

    --Eric
     
  5. ArachnidAnimal

    ArachnidAnimal

    Joined:
    Mar 3, 2015
    Posts:
    1,815
    Ok. But what do you mean by "Using the transform shortcut"?

    So basically in the above code, using:
    Code (csharp):
    1.  
    2. Quaternion q = _transform.rotation;
    3.  
    Would be an optimized version of:
    Code (csharp):
    1.  
    2. Quaternion q = gameObject.transform.rotation;
    3.  
    ?
     
  6. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    No, basically a cached version like "myTransform = transform;" then doing "myTransform.rotation = someVector;" is faster than just using "transform.rotation = someVector;", which that one would be faster than "GetComponent<Transform>().rotation = someVector;".

    Those are three separate ways to do the same thing differently :D
     
    ArachnidAnimal likes this.
  7. GroZZleR

    GroZZleR

    Joined:
    Feb 1, 2015
    Posts:
    3,201
  8. ArachnidAnimal

    ArachnidAnimal

    Joined:
    Mar 3, 2015
    Posts:
    1,815
    This is exactly why usually code optimizations are a WASTE OF TIME.
    Another optimization which goes around the forums involves eliminating empty LateUpdate() and FixedUpdate() functions. This appears to not be worth the effort also. I should probably focus on other areas instead now.
    Thanks.
     
  9. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    The answer to this is you can't cache the rotation. Rotation is a Quaternion. Quaternions are value types. Thus the rotation won't ever Update.

    Google reference versus value type for more details.
     
    lordofduct likes this.
  10. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    I know about that, but unfortunately it's not true. Perhaps they intended to do that, but it didn't happen in the released version. It's trivial to test this for yourself...don't just take someone's word for it, not even Unity's.

    You should definitely remove empty *Update functions. If they exist, they have overhead (involving reflection) even if there's nothing in them, plus they make your code ugly. It's hardly "effort" to remove them.

    --Eric
     
    KristianDoyle, Kiwasi and MD_Reptile like this.
  11. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    Oh I hadn't noticed that (the page saying it is true - or the fact that it is wrong, haha) but interesting findings there.
     
  12. BenZed

    BenZed

    Joined:
    May 29, 2014
    Posts:
    524
    Why would you have empty FixedUpdate or LateUpdate functions in your code?
     
    Kiwasi likes this.
  13. ArachnidAnimal

    ArachnidAnimal

    Joined:
    Mar 3, 2015
    Posts:
    1,815
    Did I say I had empty fixedUpdate or lateUpdate functions?
     
  14. BenZed

    BenZed

    Joined:
    May 29, 2014
    Posts:
    524
    Not you specifically, why would anyone? You said that removing empty methods is not a code improvement. Regardless of weather it is or not, why would anyone have empty functions in their code?
     
  15. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Your all wrong. You should totally spend the effort to write in empty FixedUpdate and LateUpdate functions... o_O
     
    ArachnidAnimal and BenZed like this.
  16. BenZed

    BenZed

    Joined:
    May 29, 2014
    Posts:
    524
    Better yet, make them recursive:

    Code (CSharp):
    1. void FixedUpdate()
    2. {
    3.     //1. Write recursive function
    4.     FixedUpdate();
    5. }
    6.  
    7. //2. ?????
    8.  
    9. //3:
    10. void Profit() {}
     
    NomadKing, Kiwasi and ArachnidAnimal like this.
  17. ArachnidAnimal

    ArachnidAnimal

    Joined:
    Mar 3, 2015
    Posts:
    1,815
    Take the following for example:
    when i started unity a few months ago I had the following in each of my scripts:

    Code (csharp):
    1.  
    2. currentUpdateType  = UPDATE;
    3. public void Update()
    4. {
    5.     if (currentUpdateType  == UPDATE)
    6.          PerformUpdate();
    7. }
    8. pulic void FixedUpdate()
    9. {
    10.     if (currentUpdateType  == FIXED_UPDATE;
    11.          PerformUpdate();
    12. }
    13.  
    14. public void PerformUpdate()
    15. {
    16. //..do whatever needs to be done
    17. }
    18.  
    This allowed my to just change the currentUpdate variable based on what type of update I wanted to use.
    sometimes it was needed to change to a different update type during runtime.
    For example, i have a player moving in Update in certain scenes. but then in other scenes, the player is moved in FixedUpdate instead because it is being moved externally by some physics force. Then it can switch back to Update.

    But, could not someone consider one of these functions to be "empty" at any given time? If currentUpdate = UPDATE, then technically FIxedUpdate is "empty". And vice-versa. This is why I wondered if its really worth the "effort" to change something like this just for optimization.

    (I was using this same template for every class).
    Then i went and deleted all the above updates in every class if they werent actually needed, but did not really notice any performance increase in the profiler.
    I can see if someone had hundreds of these, it might impact performance, but i cant image 10 scripts would have that big of an impact.

    Code (csharp):
    1.  
    2. if (! itIsBroken())
    3. {
    4.    dontFixIt();
    5. }
    6.  
    As far as the caching transform, I went ahead now and did that, just to get the most possible optimizations.
     
    Last edited: Jun 21, 2015
  18. Eric5h5

    Eric5h5

    Volunteer Moderator Moderator

    Joined:
    Jul 19, 2006
    Posts:
    32,401
    Technically it's not empty at all...an empty function has no code in it. Testing for a condition and then returning if false is not empty by any definition; you're doing valid work.

    --Eric
     
    BenZed and Kiwasi like this.