How does this pattern optimize compilation time compared to recursion at runtime?

I understand a well-known example of creating factorial compilation time calculations using templates, so that recursive runtime calculations are not needed. In this example, all the necessary values โ€‹โ€‹for the calculations are known at compile time.

But I looked at this other example of using patterns to calculate the power of a number, and I just donโ€™t understand how this optimization is compared to a similar recursive run-time function:

template<int n> inline int power(const int& m) { return power<n-1>(m)*m;} template<> inline int power<1>(const int& m) { return m;} template<> inline int power<0>(const int& m) { return 1;} cout << power<3>(m)<<endl; 

Obviously, m cannot be known at compile time in this example. Thus, at run time, a series of calculations will be performed that will essentially have the same value as m*m*m , right?

Is this a clear advantage for such a template? Maybe I just donโ€™t see it.

+4
source share
2 answers

You can only take advantage of template metaprogramming if you know X and Y as at compile time. Code example:

 template<unsigned int X, unsigned int N> struct Power { static const unsigned int value = X * Power<X,N-1>::value; }; template<unsigned int X> struct Power<X,0> { static const unsigned int value = 1; }; 

Usage: Power<X,Y>::value to determine X^Y
Demo

In your published code (which is used when using template , but not metaprogramming!), Only Y known at compile time, and X is passed as a run-time parameter. This means that the result will also be calculated at runtime, and we must rely on optimizations based on the compiler. It is better to use std::pow(..) in such cases.

+3
source

The difference is that this code should be created at compile time, which probably gives the optimizer more chances to notice that this is just a long sequence of multiplications.

This is basically a hunch about optimizer implementation. Perhaps it would be better to embed various instances of the templates (since templates are often used) than when inserting recursion (where you need to detect the static state of the stop) or expand the loops.

0
source

Source: https://habr.com/ru/post/1482703/


All Articles