Ver Mensaje Individual
  #6 (permalink)  
Antiguo 09/11/2016, 08:10
eferion
 
Fecha de Ingreso: octubre-2014
Ubicación: Madrid
Mensajes: 1.212
Antigüedad: 9 años, 7 meses
Puntos: 204
Respuesta: Modificar un digito de un numero

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 original
  1. template<int E> struct Exponente
  2. {
  3.     enum { value = 10 * Exponente<E-1>::value };
  4. };
  5.  
  6. template<> struct Exponente<0>
  7. {
  8.     enum{ value = 1 };
  9. };
  10.  
  11. template<int E> unsigned long ExponenteVTemplate(int)
  12. { return Exponente<E>::value; }
  13.  
  14. constexpr unsigned long ExponenteVConstExpr(int e)
  15. {
  16.   return (e>0)? 10*ExponenteVConstExpr(e-1) : 1;
  17. }
  18.  
  19. unsigned long ExponenteVRecursivo(int e)
  20. {
  21.   return (e>0)? 10*ExponenteVRecursivo(e-1) : 1;
  22. }
  23.  
  24. unsigned long ExponenteVIterativo(int e)
  25. {
  26.   unsigned long toReturn = 1;
  27.  
  28.   while( e )
  29.   {
  30.     toReturn *= 10;
  31.     e--;
  32.   }
  33.  
  34.   return toReturn;
  35. }
  36.  
  37. template<class T>
  38. void Test(T func, const std::string& msg)
  39. {
  40.   auto begin = std::clock();
  41.  
  42.   unsigned long accum = 0;
  43.   for( unsigned long i=0; i<100000000;i++ )
  44.   {
  45.     accum += func(7);
  46.   }
  47.  
  48.   std::cout << "Tiempo de " << msg << ": " << static_cast<float>(std::clock()-begin)/CLOCKS_PER_SEC << '\n';
  49. }
  50.  
  51. int main()
  52. {
  53.   Test(ExponenteVTemplate<7>,"version template ");
  54.   Test(ExponenteVConstExpr,  "version constexpr");
  55.   Test(ExponenteVRecursivo,  "version recursiva");
  56.   Test(ExponenteVIterativo,  "version iterativa");
  57. }

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 original
  1. Tiempo de version template : 0.145
  2. Tiempo de version constexpr: 0.483
  3. Tiempo de version recursiva: 0.543
  4. 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
__________________
La ayuda se paga con esfuerzo o con dinero. Si no estás dispuesto a esforzarte y quieres que te hagan los deberes pide presupuesto, al menos así ahorrarás tiempo.

Última edición por eferion; 09/11/2016 a las 08:17