Para comparar los tiempos de ejecución de los scripts entre diferentes shells, algunas respuestas de SE sugieren usar bash
el comando incorporado de la siguiente time
manera:
time bash -c 'foo.sh'
time dash -c 'foo.sh'
... etc , para cada shell para probar. Tales puntos de referencia no logran eliminar el tiempo tomado para cada shell para cargar e inicializar sí . Por ejemplo, suponga que los dos comandos anteriores se almacenaron en un dispositivo lento con la velocidad de lectura de un disquete anterior , (124KB / s), dash
(un ejecutable de ~ 150K ) se cargaría aproximadamente 7 veces más rápido que bash
( ~ 1M ), el shell el tiempo de carga sesgaría los time
números: los tiempos de precarga de esos proyectiles son irrelevantes para medir los tiempos de ejecución foo.sh
debajo de cada proyectil después de cargar los proyectiles.
Cuál es la mejor util portátil y en general a una duración de tiempo de la escritura que se pueden ejecutar desde dentro de cada capa? Entonces, el código anterior se vería así:
bash -c 'general_timer_util foo.sh'
dash -c 'general_timer_util foo.sh'
NB: no hay comandos integrados de shell time
, ya que ninguno es portátil o general.
Mejor aún si la utilidad también es capaz de comparar el tiempo que tardan los comandos internos y las canalizaciones de un shell, sin que el usuario tenga que envolverlos primero en un script. La sintaxis artificial como esta ayudaría:
general_timer_util "while read x ; do echo x ; done < foo"
Algunos proyectiles time
pueden manejar esto. Por ejemplo bash -c "time while false ; do : ; done"
funciona. Para ver qué funciona (y qué no) en su sistema, intente:
tail +2 /etc/shells |
while read s ; do
echo $s ; $s -c "time while false ; do : ; done" ; echo ----
done
/usr/bin/time
?Respuestas:
Debe tener en cuenta que
time
POSIX lo especifica , y AFAICT es la única opción que POSIX menciona (-p
) es compatible con varios shells:fuente
time
. Es comparable a dejar que los velocistas midan su propio tiempo en 100 m, individualmente, en lugar de hacerlo con un reloj al mismo tiempo. Obviamente, esto es una trampa, pero aún así ...time
que no era portátil; Parece ser portátil. (Sin embargo, estoy de acuerdo con su punto de comparabilidad)dash -c 'time -p while false ; do : ; done'
devuelve "tiempo: no se puede ejecutar mientras: No existe dicho archivo o directorio <cr> Comando salido con errores de estado no cero 127" .Uso el comando GNU
date
, que admite un temporizador de alta resolución:Y luego llamo al guión así:
La unidad de salida está en milisegundos.
fuente
date
específicamente.START
yEND
está configurado, entonces esto obviamente afectaría su resultado. No tengo idea de cuán preciso lo necesita y si importa en su caso, pero como dije, algo a tener en cuenta. (Historia divertida: Sé un software en el que es exactamente lo que condujo a un resultado inesperadamente negativos - se utiliza para cálculos de rendimiento - que luego se rompieron algunas cosas.)La
time
utilidad generalmente está integrada en el shell, como se habrá dado cuenta, lo que la hace inútil como un temporizador "neutral".Sin embargo, la utilidad generalmente también está disponible como una utilidad externa
/usr/bin/time
, que bien puede usarse para realizar los experimentos de temporización que usted propone.fuente
foo.sh
es ejecutable y tiene un shebang, esto siempre lo ejecuta con el mismo shell, y cuenta el tiempo de inicio de ese shell, por lo que esto no es lo que OP quiere. Sifoo.sh
falta uno de esos, entonces esto no funciona en absoluto.time
Parece que solo tomé en cuenta "sin shell incorporado ". Es posible que el tiempo de inicio del shell deba medirse por separado.time
comando incorporado. Sin embargo, muchos shells incluyenbash
unatime
palabra clave que se puede usar para cronometrar tuberías. Para deshabilitar esa palabra clave para quetime
se use el comando (en el sistema de archivos), puede citarla como"time" foo.sh
. Ver también unix.stackexchange.com/search?q=user%3A22565+time+keywordAquí hay una solución que:
Hay dos partes: un programa C corto que finaliza
gettimeofday
, que está en desuso pero aún más portátil queclock_gettime
, y un script de shell corto que usa ese programa para obtener un reloj de precisión de microsegundos que lee ambos lados de la fuente de un script. El programa C es la única forma portátil y mínima para obtener una precisión de menos de un segundo en una marca de tiempo.Aquí está el programa C
epoch.c
:Y el script de shell
timer
:Esta es la norma lenguaje de comandos shell y
bc
y debería funcionar como un guión bajo cualquier shell compatible con POSIX.Puedes usar esto como:
No mide el tiempo del sistema o del usuario, solo el tiempo transcurrido del reloj de pared no monótono. Si el reloj del sistema cambia durante la ejecución del script, esto dará resultados incorrectos. Si el sistema está bajo carga, el resultado será poco confiable. No creo que nada mejor pueda ser portátil entre proyectiles.
Un script de temporizador modificado podría usarse
eval
en su lugar para ejecutar comandos fuera de un script.fuente
eval
), estaba modificando el guión en la respuesta de Rabin para incluirloeval "$@"
, de modo que pudiera ejecutar construcciones de shell sobre la marcha.Solución revisada varias veces usando
/proc/uptime
ydc
/bc
/awk
en partes grandes gracias a la entrada de agc :Asume obviamente que
/proc/uptime
existe y tiene una cierta forma.fuente
/proc
sistema de archivos. Si esto es una preocupación o no, no lo sé.awk
puede ser significativa. Tal vezb=$(cat /proc/uptime)
antes, luegoa=$(cat /proc/uptime)
después, luego analice $ a y $ b y reste.read
son mejores quecat
, esto sería más limpia (y un poco más rápido):read before dummyvar < /proc/uptime ;sleep 2s;read after dummyvar < /proc/uptime; duration=$(dc -e "${after} ${before} - n");echo "It took $duration seconds."