Following a profiling of my C++ code, it appears that the pow
function is used a lot.
Some of my pow
functions have an integer exponent and another non-integer exponent. I am only interested for the ones with integer exponent.
To gain in performance, I am looking a way to define a macro like this:
#define pow(x,n) ({\
double product;\
if (typeid(n).name() == "i") {\
for(int i = 0; i < n-1; i++)\
product *= x;}\
else\
product = pow(x,n);\
product;\
})
But I don't get the gain expected regarding the runtime. I think this is due to the else
part in my macro where I call the classical pow
function.
How can I determine in advance the type of exponent before macro was "written" during the pre-processing?
Ideally, I would like this macro only to be applied if the exponent is an integer, but it seems my attempt is not pertinent.
From your suggestions, I tried three options:
First option: Just add overload inline functions with base which is integer
or double
:
// First option
inline int pow(int x, int n){
// using simple mechanism for repeated multiplication
int product = 1;
for(int i = 0; i < n; i++){
product *= x;
}
return product;
}
inline int pow(double x, int n){
// using simple mechanism for repeated multiplication
double product = 1;
for(int i = 0; i < n; i++){
product *= x;
}
return product;
}
Result: runtime = 1 min 08 sec
Second option: Define a macro that calls via inline my_pow
function if the exponent n
is not an integer:
// Second option
inline double my_pow(double x, double n){
return pow(x,n);
}
#define pow(x,n) ({\
double product = 1;\
if (typeid(n) == typeid(int)) {\
for(int i = 0; i < n; i++)\
product *= x;}\
else product = my_pow(x,n);\
product;\
})
Result: runtime = 51.86 sec
Third option: suggestion given in answer with template<typename type_t>
template<typename type_t>
inline double pow(const double x, type_t n)
{
// This is compile time checking of types.
// Don't use the RTTI thing you are trying to do
//if constexpr (is_floating_point_v<type_t>)
if (typeid(n) != typeid(int))
{
return pow(x, n);
}
else
{
double value = 1;
for (type_t i = 0; i < n; ++i) value *= x;
return value;
}
}
Result: runtime = 52.84 sec
So finally, from these first tests, the best option would be the second one where I use a macro combined with a function that calls the general case of the pow
function (both integer and floating exponent).
Is there a more efficient solution or is the second option the best?