开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜