Why is Transform.position or even worst Transform.forward so expensive?

The following code was used to get these results. I purposefully didn’t cache some of those components since I wanted to test how much time it takes to get them. For some of them, I did reuse the component to ensure everything was called the same number of times (at least on the surface as some of them call some of the others to get the job done).

for (int i = 0; i < 25000; i++)
        {
            GameObject thisGameObject = gameObject;
            Transform myTransform = transform;
            Vector3 myPosition = myTransform.position;
            Quaternion myRotation = myTransform.rotation;
            Rigidbody myRigidBody = rigidbody;
            Vector3 myDirection = myTransform.forward;
            int myLayer = thisGameObject.layer;
            Renderer myRenderer = renderer;
            Material myMaterial = myRenderer.material;
            Color myColor = myMaterial.color;
        }

Now some Components like (Transform, RigidBody, Material ) are easy to cache to avoid these costs since getting a reference to them works and from frame to frame, they don’t really change. However, others like transform.up / .forward / .position / .rotation (those we tend to check way more frequently sometimes each frame) and even if you had cached their transform are still going to hit you hard.

I realize that no one will loop through these like that but this does illustrate their relative cost to each other. So unless I am missing something here, is there any way to avoid some of those hits? Caching the transform of a component for which you may want to get the .forward of is good practice but that cost relative to using .forward is pretty small. For certain, within a pass / loop or whatever, I’ll be sure to create a local variable to hold myTransform.forward if i am going to use it more than once :slight_smile: or any of these more costly .get_“something”.

I am relatively new to programming so I could be way off the deep end here so please enlighten me if I stayed wrong somewhere :slight_smile:

P.S. I left out transform.tag … it’s a slightly more expensive than .position or .rotation plus it loves to bring GC.Collect with it … so compared to how inexpensive .layer is … I stay away from strings

Uploaded with ImageShack.us

There’s not really that much you can do that I can think of. The things that return a value (get_position, get_rotation, get_color) are going to take more time because it has to make a copy of the struct instead of just returning a reference to the component. transform.forward is even more expensive because not only does it have to fetch the rotation, it then has to do some math to calculate the forward vector based on that rotation.

But, in your example, even Transform.get_forward() only takes 0.00156ms. Squeezing a bit more performance out of it somehow is probably not going to make much difference in your game. Premature optimization is the root of all evil, or so I’ve heard.

I can see how :slight_smile:

Since I am still in the early learning phases, I want to be mindful of those things to make sure I don’t end up developing something that will cause another wise person to say “Development with little or too late regard to Optimization, is the root of all evil” :slight_smile:

.tag is part of GameObject, not Transform (it’s inherited in Transform). Always use CompareTag instead of a standard string compare. And yes, what noisop said…don’t worry about it unless it’s actually causing a performance issue. You’d need to be using thousands of objects running stuff every frame for it to really matter, but by then you probably have bigger problems anyway (such as rendering them, for example).

–Eric

Thank you both!