Reputation: 1718
I have two functions void f(int x){...}
and void g(int x){f(x);}
. I know 99% of the time g()
receives 3 or 5. In f()
, x
never changes and supervises lots of loops and condition branches. Would the following be faster than my original code ?
void g(int x)
{
if(x == 3) f(3);
else if(x == 5) f(5);
else f(x);
}
Would the compiler (g++ -Ofast
) compile f(3)
and f(5)
seperately from f(x)
, analogous to compiling two template parameters ? What else should I do to let the compiler acknowledge the optimization opportunity more easily ? Is declaring void f(const int &x){...}
helpful or necessary ?
Upvotes: 3
Views: 108
Reputation: 6131
If this is a performance critical function, and 99% of the time f(3) or f(5) is called, and you are trying to optimize, you should measure the difference of such calls. If f() is an inline function, the optimizer may be able to work with your constant better than a variable, to make some of its functionality evaluate at compile time (such as constant folding, strength reduction, etc.) It might be useful Godbolt.org to look at the assembly and see if any obvious improvements occur. LTO may also help even if it's not inlined, though different people report different levels of success with this.
If you don't see much improvement but think there could be some knowing x in advance, you could also consider writing different specialized versions of f(), such as f3() and f5() which are optimized for those cases (though you might also end up with a larger instruction and have icache issues. It all comes down to measuring what you try and seeing where the benefits (and losses) are. Most important thing is to measure. It's no fun making code complicated for no gain (or worse, to slow it down in the name of optimization.)
Upvotes: 1
Reputation: 98425
Answers to such questions are ultimately misleading, because they depend not only on the exact environment you use, but also on the other code your project will link with, should link-time optimization be used. Furthermore, the compiler can generate multiple versions — some more “optimal”, and then the “optimality” depends on who’s calling g()
. If g()
is constexpr - make it so, the compiler could use that fact to guide optimizations.
In any case: you need to look at the output of your compiler; with the code as it is compiled into your project. Only then you can tell. As a prelude, you should head to Compiler Explorer at https://godbolt.org and see for yourself in an isolated environment.
Upvotes: 1