If you have a method such as this:
float method(myClass foo)
{
return foo.PrivateVar() + foo.PrivateVar();
}
is it always faster/better to do this instead?:
float method(myClass foo)
{
float temp = foo.PrivateVar();
return temp + temp;
}
I know you’re not supposed to put a call like foo.PrivateVar() in a for loop for example, because it evaluates it many times when you actually only need to use the value once (in some cases.
for (int i = 0; i < foo.PrivateInt(); i++)
{
//iterate through stuff with 'i'
}
from this I made the assumption to change code like the first example to that in the second, but then I’ve been told by people to not try to be smarter than the compiler! and that it could very well inline the calls.
I don’t want to profile anything, I just want a few simple rules for good practice on this. I’m writing a demo for a job application and I don’t want anyone to look at the code and see some rookie mistake.
That completely depends on what
PrivateVar()is doing and where it’s defined etc. If the compiler has access to the code inPrivateVar()and can guarantee that there are no side effects by calling the function it can do CSE which is basically what you’ve done in your second code example.Exactly the same is true for your for loop. So if you want to be sure it’s only evaluated once because it’s a hugely expensive function (which also means that guaranteeing no side-effects get’s tricky even if there aren’t any) write it explicitly.
If
PrivateVar()is just a getter, write the clearer code – even if the compiler may not do CSE the performance difference won’t matter in 99.9999% of all cases.Edit: CSE stands for Common Subexpression eliminiation and does exactly what it stands for 😉 The wiki page shows an example for a simple multiplication, but we can do this for larger code constructs just as well, like for example a function call.
In all cases we have to guarantee that only evaluating the code once doesn’t change the semantics, i.e. doing CSE for this code:
and changing it to:
would obviously be illegal (for function calls this is obviously a bit more complex, but it’s the same principle).