Para lo que estás haciendo te va a dar prácticamente igual porque el número de iteraciones es ridículo y para ejemplo el siguiente código:
Código C++:
Ver originaltemplate<int E> struct Exponente
{
enum { value = 10 * Exponente<E-1>::value };
};
template<> struct Exponente<0>
{
enum{ value = 1 };
};
template<int E> unsigned long ExponenteVTemplate(int)
{ return Exponente<E>::value; }
constexpr unsigned long ExponenteVConstExpr(int e)
{
return (e>0)? 10*ExponenteVConstExpr(e-1) : 1;
}
unsigned long ExponenteVRecursivo(int e)
{
return (e>0)? 10*ExponenteVRecursivo(e-1) : 1;
}
unsigned long ExponenteVIterativo(int e)
{
unsigned long toReturn = 1;
while( e )
{
toReturn *= 10;
e--;
}
return toReturn;
}
template<class T>
void Test(T func, const std::string& msg)
{
auto begin
= std
::clock();
unsigned long accum = 0;
for( unsigned long i=0; i<100000000;i++ )
{
accum += func(7);
}
std
::cout << "Tiempo de " << msg
<< ": " << static_cast
<float
>(std
::clock()-begin
)/CLOCKS_PER_SEC
<< '\n';}
int main()
{
Test(ExponenteVTemplate<7>,"version template ");
Test(ExponenteVConstExpr, "version constexpr");
Test(ExponenteVRecursivo, "version recursiva");
Test(ExponenteVIterativo, "version iterativa");
}
El template
Test lo he creado únicamente para no tener que duplicar el bucle y el contador de tiempo.
En mi caso aparecen los siguientes resultados:
Código resultado:
Ver originalTiempo de version template : 0.145
Tiempo de version constexpr: 0.483
Tiempo de version recursiva: 0.543
Tiempo de version iterativa: 0.521
Verás que salvo en el caso de la versión template los tiempos son prácticamente similares y esto es debido a que el coste de las multiplicaciones es muy superior al coste del resto de las operaciones. Eso sí, la versión de templates tiene un par de desventajas:
- La profundidad de la recursividad está limitada en función del compilador, luego no te sirve para todas las situaciones.
- Usar el template te exige saber con antelación el exponente a utilizar, ya que ese valor hay que proporcionarlo en tiempo de compilación. Este detalle impide que puedas, por ejemplo, usar una variable para determinar el exponente que quieres calcular.
nota: La versión template usa un parámetro int al que no da uso simplemente para ser compatible con la función de Test que he diseñado. Fuera de este contexto la función no necesitaría recibir ningún argumento.
Si las funciones tuviesen un número de iteraciones significativo lo normal es que la versión iterativa fuese mejorando los tiempos respecto a la versión recursiva, ya que una función recursiva implica realizar múltiples llamadas a la función, lo que lleva a realizar muchos saltos en el código, las variables de la función estarían duplicadas en la pila, ...
En cuanto a la versión constexpr. Un detalle que se me pasó comentar es que el compilador no está obligado a calcular el valor en tiempo de compilación... sin embargo constexpr tiene otra serie de usos que no creo que entren en el alcance de la pregunta inicial... google tiene mucha información al respecto :)
Un saludo