2010-09-21 31 views
5

¿Hay alguna forma agradable de GNU de cómo medir el tiempo promedio (peor caso, el mejor caso) de ejecución de algún programa de línea de comando? Tengo filtro de imagen, cantidad no especificada de imágenes, filtrándolas usando for-loop en bash. Hasta ahora estoy usando tiempo, pero no puedo encontrar la manera de obtener algunas estadísticas.Tiempo promedio de ejecución

+0

@chown ¿Cuál es el punto del comentario anterior? –

+1

Pregunta similar que tiene algunas buenas respuestas - [bash: tiempo medio de ejecución en varias ejecuciones] (http://stackoverflow.com/questions/8215482/mean-running-time-over-a-number-of-runs/ 8216082 # 8216082). – chown

Respuesta

4

Hay un programa interesante de Perl llamado dumbbench que es esencialmente un envoltorio alrededor del comando time. Ejecuta su programa varias veces, descarta valores atípicos y luego calcula algunas estadísticas.

El autor tiene un par de artículos (here y here), que expondrá a) por qué la evaluación comparativa chupa, y b) qué tipo de gráficos bonitos que usted puede hacer para hacer que sus números de evaluación comparativa chupan un poco menos.

+0

Solo espero poder pasar diferentes parámetros para cada ejecución, lo probaré esta noche. –

2

Estás en el camino correcto con time. Es lo que uso para realizar pequeños análisis de ejecución de código.

Luego uso python para recopilar las estadísticas leyendo el resultado de time. Para aumentar la precisión, generalmente realizo la prueba de 10 a 1000 veces, dependiendo de cuánto tiempo tome cada proceso.

No estoy familiarizado con ninguna aplicación GNU preinstalada que realice este tipo de análisis.

+1

Si va a utilizar Python, es posible que desee utilizar [timeit] (http://www.python.org/doc//current/library/timeit.html). – GreenMatt

+1

De vuelta en los viejos tiempos, ejecutamos el programa 12 veces usando 'tiempo', tiramos los mejores y peores momentos, luego promediamos los 10 valores restantes. –

+0

¡Me encanta el tiempo! Solo recomiendo canalizar los datos de 'tiempo' porque no quiero que Python controle la ejecución de mis comandos y, por lo tanto, puede ralentizar la ejecución al capturar stdin y whatnot. Es algo así como, debería usar C o debería usar Python: ese tipo de sentimiento. – Sean

6

Puede enviar la salida de tiempo para algún archivo, y luego "trabajar" ese archivo

echo "some info" >> timefile.txt 
time (./yourprog parm1 parm2) 2>> timefile.txt 
+2

No necesita los paréntesis. –

+0

En mi computadora (versión bash 4.1.5 (1) -release (x86_64-pc-linux-gnu)), sin el paréntesis, el '2 >>' se aplica al programa interno – pmg

+0

@DennisWilliamson Mismo aquí, yo también * * do ** necesita los parens. – chown

2
#!/bin/bash 
for i in {1..100} 
do 
    env time --append -o time_output.txt ./test_program --arguments-to-test-program 
done 
exit 

Si encuentra que la sintaxis {1..100} no funciona para usted entonces deberías echarle un vistazo al comando seq.

Utilicé el env time para ejecutar el programa de tiempo en lugar del comando incorporado del shell, que no toma todos los argumentos que toma el programa de tiempo. El programa de tiempo también toma otros argumentos para alterar el formato de su salida, que probablemente desee utilizar para facilitar el proceso de otros programas. El argumento -p (portabilidad) lo hace salir en formato POSIX (como lo hace el tiempo incorporado de BASH), pero usando la opción -f puede obtener más control. man 1 time para más información.

Después de haber recopilado sus datos, un script simple de perl o python puede analizar y analizar fácilmente sus datos de tiempo.

+0

No tiene que usar 'seq'. Puedes hacer 'for ((i = 1; i <= 100; i ++))'. –

+0

Si es posible, quiero evitar escribir mi propio analizador si alguien más lo hizo. –

0

Debería considerar si sincronizar el ciclo externo y dividir por las repeticiones en lugar de sincronizar cada iteración por separado. Si le preocupa descartar lo alto y lo bajo, solo haga algunas iteraciones más para ahogarlos.

time for i in {1..1000} 
do 
    something 
done 

Puede capture the output from time in a variable:

foo=$({ time { 
    echo "stdout test message demo" 
    for i in {1..30} 
    do 
     something 
    done 
    echo "stderr test message demo" >&2 
} 1>&3 2>&4; } 2>&1) 

y hacer un poco de matemáticas falsa:

foo=${foo/.}   # "divide" by ... 
echo "0.00${foo/#0}" # ... 1000 

o simplemente utilizar bc:

echo "scale=8; $foo/1000" | bc 
Cuestiones relacionadas