Tengo dos scripts que cada uno calcula el factorial de un número. Me gustaría saber cuál es más rápido. El time
comando me da milisegundos y el resultado es diferente de vez en cuando:
piousbox@piousbox-laptop:~/projects/trash$ time ruby fac2.rb
30414093201713378043612608166064768844377641568960512000000000000
real 0m0.089s
user 0m0.052s
sys 0m0.028s
piousbox@piousbox-laptop:~/projects/trash$ time ruby fac1.rb
30414093201713378043612608166064768844377641568960512000000000000
real 0m0.091s
user 0m0.048s
sys 0m0.036s
piousbox@piousbox-laptop:~/projects/trash$ time ruby fac1.rb
30414093201713378043612608166064768844377641568960512000000000000
real 0m0.088s
user 0m0.048s
sys 0m0.040s
piousbox@piousbox-laptop:~/projects/trash$ time ruby fac2.rb
30414093201713378043612608166064768844377641568960512000000000000
real 0m0.088s
user 0m0.048s
sys 0m0.028s
piousbox@piousbox-laptop:~/projects/trash$ time ruby fac1.rb
30414093201713378043612608166064768844377641568960512000000000000
real 0m0.087s
user 0m0.064s
sys 0m0.028s
piousbox@piousbox-laptop:~/projects/trash$ time ruby fac2.rb
30414093201713378043612608166064768844377641568960512000000000000
real 0m0.089s
user 0m0.068s
sys 0m0.016s
piousbox@piousbox-laptop:~/projects/trash$
¿Cómo tomo el tiempo promedio para ejecutar el script? Podría analizar y promediar la salida de un 100 time
pero imagino que hay una mejor solución.
Respuestas:
No, tu idea de promediar es correcta.
La ejecución de la secuencia de comandos depende de muchos factores y, sin embargo, debe dividirse entre el tiempo de configuración (carga del intérprete en la memoria, configuración y posiblemente compilación de código a código de bytes o código de máquina) y el tiempo de ejecución real.
Para centrarse mejor en el tiempo de ejecución interno, realice el bucle en el script en sí (es decir, en lugar de calcular un factorial, lo calcula 100 veces dentro de una ejecución del script. El script se configurará una vez y la rutina interna ejecutará 100 veces).
Para centrarse en el tiempo total, ejecuta el script cien veces y promedia los resultados. Idealmente, debe separar esas ejecuciones lo suficiente como para que el sistema regrese en un "estado de referencia" (o un estado no relacionado con el script) cada vez. Por ejemplo, el propio intérprete se almacenará en la memoria caché, de modo que la primera ejecución del guión será considerablemente más lenta que las posteriores.
Para obtener una mejor visión del algoritmo, creo que la mejor manera es algo como esto (en una máquina inactiva):
La aplicación solo se ejecuta una vez, toda la configuración y cebado se realiza mediante la primera iteración no programada, por lo que esto debería minimizar los gastos generales (excepto tal vez por la llamada de tiempo).
Si la función recibe una entrada, haría bien en proporcionarle una secuencia aleatoria de entradas utilizando un PRNG sembrado con un valor fijo, para asegurarse de que ambas versiones de la función que se está probando reciban los mismos valores. Esto evita que una función tenga un rendimiento aparentemente mejor debido a los "números de la suerte" (p. Ej., Recuerdo una variación del algoritmo de Hillsort que funcionó considerablemente mejor si el número de elementos que se ordenarían tenía la forma 2 k -1 con pequeñas k s).
fuente
Puede ejecutar iteraciones del programa en un bucle; y divide el tiempo total entre el número de iteraciones:
fuente
{1..10}
antes y estoy desconcertado de que funcione, no puedo encontrarlo en el manual de bash. Lo único triste es que no conoce la difusión de sus resultados (tiempo mínimo y máximo).man -P 'less +/Brace\ Expansion' bash
bash
. Intenta correr/bin/bash
antes de esto.existe una herramienta llamada multitime que hace exactamente esto: ejecutar un comando varias veces, medir cuánto tiempo se tarda (tiempo real / usuario / sistema con tiempo medio, mínimo / máximo y mediana calculados automáticamente)
Por ejemplo, para medir un script similar 100 veces:
fuente
Esto es antiguo, pero apareció en Google cuando estaba buscando un comando que utilicé anteriormente pero que no pude encontrar. De todos modos, mi forma preferida de hacer esto es:
Esto proporciona bastantes detalles, incluido el tiempo de ejecución promedio al final:
fuente
Para
-n
,-r
y otras opciones ver https://docs.python.org/2/library/timeit.html#command-line-interfacefuente
Hiperfina es otra opción.
Uso de la muestra:
fuente