Changing a normal function to template will make any positive/negative difference?
I have a wrapper function (templatized) Outer()
and core functionality function as Inner()
.
namespace N
{
A* Inner (void *p, int value, const int ID);
template<typename T>
A* Outer (T *p, const int ID) // ID is a compile time constant
{
return Inner (p, p->value, ID);
}
}
Usage:
A *px = Outer(new X(3), 12345);
A *py = Outer(new Y(4), 987);
I am managed to pass a comp开发者_开发百科ile-time constant as ID. So I am thinking of changing the Outer()
prototype to,
template<int ID, typename T>
A* Outer (T *p)
{
return Inner (p, p->value, ID);
}
Which will be used as,
A *pz = Outer<333>(new Z(5));
Wanted to know that, is there any code/performance level impact with the new approach ? Will there be any impact on inlining ?
Edit: ID is surely at compile time and there are several instances of Outer()
appearing (that's why it is important to know about inline
also).
First of all, since ID is supposed to be an int
, the template should be
template<int ID, typename T>
A* Outer (T *p)
...
Moving on, though, as far as ups and downs go, it sort of depends on your usage, but here are some sure facts:
Performance
There really shouldn't be any appreciable difference. Since a new function will be created for each value of ID
, it should performs as if you had just declared your own separate function with a local ID
constant. So the template version might be quicker because no copying of values occurs at the function call, but like I said, it probably won't be significant enough to be a deal-breaker.
Usage
The two forms are really not equivalent. Since the function definition is defined at compile-time depending on the value of ID
, only compile time constants can be used (which it seems you are expecting). In the original version, a user could write
int i = 10;
Outer<Z>(new Z(5), i);
Although i
is a variable, it is copied to ID
as a constant value.
In the template version, they cannot write
int i = 10;
Outer<i, Z>(new Z(5));
Since the compiler generates a different function for each value of ID
, it can't possibly create a function at compile-time when the value isn't know until runtime
So your original version is a lot more flexible, while your proposed change is very rigid. I think most people would want to use the function in the original way, where they aren't forced to used compile-time constants. So I would stick with the original unless for some reason you really need the ID
value to be a compile-time constant.
Compiled Code
For the compiled code, your binary will be larger (assuming you use the function for at least two different values of ID
). This is because a new function is created for each different value of ID which is used in the program. So if you expect many different values to be used, bloat in your binary could be potentially become an issue
Inlining
This is something I do not have a definite answer to. I am guessing that if inlining is affected, it would probably be affected by the parameter T
rather than ID
.
None. The function is a template and therefore must be inlined, and constant folding like this is one of the most common optimizations done when functions are inlined. This suggests that if you have a modern compiler, it will make absolutely no difference whatsoever.
Assuming you do it correctly (the code has the same functionality), then the only penalty introduced is the compilation time increase, because compiling templates takes longer then compiling normal function.
You can say "I have super fast computer, and compilation takes 1/2 second", but for big projects it matters a lot.
It will depend on your compiler and how the functions are used. In practice, if you've got optimization turned up, the only difference I think you'll see is in the calling syntax. But if you have a performance problem, profile and see where it's coming from.
精彩评论