- Home /
Performance Optimization ~Function Update: Loop or Once ?
I didnt manage to find any similar question so its good to ask. As the title suggests what is better for me to do in a function update if i just need the change a variable once ?
example code:
var test1 : int;
function Update() {
if (otherScriptName.otherStaticVariable == 500) { test1 = otherScriptName.otherStaticVariable; }
if (otherScriptName.otherStaticVariable == 100) { test1 = otherScriptName.otherStaticVariable; }
}
OR
var test1 : int;
var done : boolean;
function Update() {
if (otherScriptName.otherStaticVariable == 500 && !done) {
test1 = otherScriptName.otherStaticVariable;
done = true;
}
if (otherScriptName.otherStaticVariable == 100 && !done) {
test1 = otherScriptName.otherStaticVariable;
done = true;
}
}
ALSO (as i was writing i thought of that too)
var test1 : int;
function Update() {
if (otherScriptName.otherStaticVariable == 500 || otherScriptName.otherStaticVariable == 100) {
test1 = otherScriptName.otherStaticVariable;
}
}
My main question is if there is any performance difference between the 2 first examples lets say if i have each of them in 900 differenct objects. (Ofcourse this is an example code my real code is much bigger but its almost the same method and i want to know if it has an impact on performance even slightly)
Short answer: Don't worry about it. Seriously, the most important consideration is which presents its logic most clearly and is easiest for you to build/maintain.
However if you are going to use a flag like your second senario :
if (otherScriptName.otherStaticVariable == 500 && !done) {
Put the local boolean first as can be accessed faster and depending on it's value it may render the slower remote member obsolete.
if (!done && otherScriptName.otherStaticVariable == 500) {
Helpful , i didn't know about that , i guess it was worth asking.
Why not use InvokeRepeating() and CancelInvoke() method? It's more efficient than running an update that has to set a variable only once and still perform a check in the subsequent frames. Here's the code(in C#):
int test1;
void Start(){
InvokeRepeating("my$$anonymous$$ethod", 0.1f, 0.1f);
}
void my$$anonymous$$ethod(){
if(otherScriptName.otherStaticVariable == 500 || (otherScriptName.otherStaticVariable == 100){
test1 = otherScriptName.otherStaticVariable;
CancelInvoke();
}
}
You can adjust the 2nd and 3rd parameters of InvokeRepeating so that it is not too frequent.
its always worth measuring, put some timers around the code and see if you can measure differences... measurement is king for performance work - data trumps everyone's specialist knowledge every time.
Answer by PetahNZ · Jan 12, 2014 at 10:51 AM
The third example should be the best as it uses short circuit logic: http://en.wikipedia.org/wiki/Short-circuit_evaluation
What about branch penalties such as i-cache misses or misprediciton? Don't guess. $$anonymous$$easure. Its the best approach we have and the cornerstone of the scientific method.
Answer by semiessessi · Jan 12, 2014 at 08:22 PM
There is one correct approach to optimisation.
Measure performance and determine where most CPU time, memory or other resource usage is occuring
Change code in slowest/largest/most expensive areas
Measure performance in the same way as in step 1 and compare
If performance did not measurably improve then undo changes from step 2
If not fast/small/whatever enough go back to step 1
Also, high level optimisations first. If this sort of thing is genuinely causing you a performance problem then JavaScript is the wrong language for you. A good first step would be to use #pragma strict in the hopes it does something for the compiler. A next step would be to use C# and another would be to not even use Unity...
any explanation for the -1? what i advocate here is essentially the scientific method - its very well tested and responsible for the entire technology stack at work here. its also advocated by more well known optimisation gurus than myself e.g. see $$anonymous$$ichael Abrash's program$$anonymous$$g black book (http://www.nondot.org/sabre/$$anonymous$$irrored/GraphicsProgram$$anonymous$$gBlackBook/)
is it because its not an answer perhaps?
AFAI$$anonymous$$, pragma strict'd UnityScript and C# compile pretty much to the same IL, so there shouldn't be a performance difference there. Aside from that, I agree with you. But I think that generally questions like these are still important for learning good practices and to code efficiently in the first place!
Answer by Invertex · Jan 12, 2014 at 10:41 AM
var test1 : int;
function Update()
{
if ((!done) && (otherScriptName.otherStaticVariable == 500 || otherScriptName.otherStaticVariable == 100))
{
test1 = otherScriptName.otherStaticVariable;
}
}
This would be the cleanest and most efficient. First the code will check the local var if it is not done, and if it's done, then it skips everything else. But if it's !done, then it goes on to check the second argument, which is an either or, but only when !done.
When the first argument in an && statement comes back false, it doesn't bother with the rest, as there's no point, since both need to be true for the statement to pass.
hmm from what i've read this looks the most efficient and if others agree too i would vote this as correct answer but my main question is if there is any difference in performance between example 1 and 2 even if its very small.
Well, yes, you're adding an extra bool check into the 2nd option... So it's going to take the machine a few EXTRE$$anonymous$$ELY tiny more steps to go through that. The amount of performance difference we're talking here is ridiculously tiny. Readability should come first, micro-optimization very last, if at all. $$anonymous$$ost seasoned programmers say not to get caught up in that, at least from what I've read.
Yeah but what i was thinking is that the first one is beeing called each frame even if the int is already 500 it will change it to 500 again wont it ? still the second one is beeing called only one time and after that if i tweeck the variable test1 it wont be changed because bool done isnt false isn't that a difference cause i was hoping this to have an impact ?
The difference in operations happening isn't much. In #1 it doesn't do a bool check, so it's going to check the first line, and if it returns true, it write's a value equal to. 2 operations and then a third on the next line that will return false and vice versa. So it's only 2 operations when none of those are true, and 3 if one is true.
Then we look at #2, it's pretty much the same. It's 2 operations, but with the potential for 4. But if you did have the bool first, it would at least become more efficient once it became true, remaining at 2 ops.
The changing a value equal to operation isn't really any more taxing than the external boolcheck in the grand scheme of things. So either way they are pretty much the same. #2 would be quicker if it was worded with the bool first, but not in any noticeable way even if you had thousands of these running.
As per the previous answer - what about branch penalties such as i-cache misses or misprediciton? Don't guess. $$anonymous$$easure. Its the best approach we have and the cornerstone of the scientific method.
Answer by morbidcamel · Jan 12, 2014 at 10:50 AM
Guys,
When using too many variables to maintain state is usually a bad idea and will put you on the late night - early morning debugging fast track. I would suggest writing state machine type logic using an enum if it's applicable to your scenario.
...
public enum State { State1 = 100, State2 = 500, Done=0 };
...
void Update()
{
switch(state)
{
case State.State1:
...
state = State.State2;
break;
case State.State2:
state = State.Done;
break;
default:
...
break;
}
}
Answer by neonblitzer · Aug 04, 2015 at 01:46 PM
Late to the party...
But I have to point out that assigning a value to a variable is a lightning fast operation. Trying to avoid "unnecessary" assignments with checks like these may actually be slower than just assigning every time (check this question).
And, in theory, removing the check also eliminates potential branching errors. So I'd say it's good practice to try to avoid a check like this if it's not necessary for the logic and it doesn't improve readability.