Hey all-- in reading through the docs about efficiency, Unity states that doing this:
var myParent : Transform = transform.parent;
//multiple calculations using myParent
is faster than doing this:
//multiple calculations using transform.parent
I was wondering if this is something specific to UnityScript and its reflection, or would a programming language like C++ or Java or any other language with dot operators suffers from this.
Thanks!
It can be faster depending on how the language is interpreted or what operations are necessary to access “parent”. Consider:
public class MyClass
{
private AnotherClass m_InternalParent;
public AnotherClass parent
{
get
{
//simulate some long process
System.Threading.Thread.Sleep(5000);
return m_InternalParent;
}
}
}
MyClass obj = new MyClass();
obj.parent.SomeProperty = 5;
if (obj.parent.SomeProperty == 5)
{
obj.parent.SomeProperty = 0;
}
Each time it tries to access “parent”, it runs the logic that takes 5 seconds to process, so those few lines of code takes 15 seconds. Now if you rewrote it as:
MyClass obj = new MyClass();
AnotherClass theParent = obj.parent;
theParent.SomeProperty = 5;
if (theParent.SomeProperty == 5)
{
theParent.SomeProperty = 0;
}
Then it only needs to run the heavy logic once (at theParent = obj.parent) so it only takes 5 seconds.
Now, some languages are dynamically typed and so must resolve references on the fly, so even if “obj.parent” didn’t take 5 seconds or didn’t have logic in it, there would still be overhead time resolving what “obj.parent” actually references.
UnityScript, as far as I know, typically isn’t too bad from this and you’d have to access it a lot to see any measurable processing time. But some operations may be relatively costly (perhaps the “parent” lookup for transform IS a very long lookup, I don’t know, it could be) then you’d be better off only calling it once and storing/reusing the reference. So I wouldn’t necessarily suggest that you do this religiously (every single time you use it only twice you store/reuse a reference), but just do it when it makes sense. (such as when you access it many, many times or when that lookup is costly)
So that is related to dynamically typed languages-- then I’d expect the same things from PERL and PHP–
Of course, what you said, there is probably going to be no measurable difference, and I don’t really think there will be.
For any stray dog who happens to find this post, there is also info that using Update is faster then Fixed Update because it is run fewer times over the course of a game step.
Some “dynamically” typed languages can perform on-the-fly compilation, so it may not always be true. (for example, JavaScript compiles in Google Chrome when possible)
In Unity’s case, the biggest slowdown would likely come from the logic required to retrieve what that parent is. If it’s just a straight up field, then it should be negligible. But if it’s a more intensive process (possibly crawling the scene graph of objects) then it’s worthwhile to only do that work once.
This particular problem isn’t to do with dynamic typing. MonoBehaviour.transform is not a variable but a property. This means that code must be executed to retrieve the transform component. That being the case, it is best to save a copy of it once you have accessed it to avoid executing the property code again. This optimisation won’t make much difference in most code, but it could save time if you have a loop where the transform is used repeatedly.
The Property access stuff is what Andeeee said in that you are accessing a Property which functions like a function, but is accessed like a variable. The code being processed is slower than just accessing the reference directly, but it really depends on the property itself to determine exactly how much slower. Also, I was under the understanding that some of the properties like transform or camera are not cached and are calling a GetComponent search every access, rather than holding onto the reference (much faster). That second part however is just pure assumptions.
Properties are interesting little accessors that can provide callbacks when modified, or limit input values. Think of them as Get/Set functions from other languages but wrapped up so they are accessed like the actual variables themselves. But that extra processing takes time.
The Update - FixedUpdate really depends on your physics settings.
Update is run as fast as possible.
FixedUpdate is run at fixed intervals set by you.
You can set FixedUpdate to be faster than Update but it is not always the case.
Also Update is called between Renders, whereas FixedUpdate can occur multiple times between a single Frame, or can have many frames occur between an FixedUpdate.