¿Cómo obtener el tiempo de ejecución de Bash en milisegundos en Mac OS X?

12

He comprobado esto , pero la solución proporcionada no funcionó para mí.

Usando la fecha puedo obtener el tiempo de ejecución en segundos:

T="$(date +%s)"
#some work here
T="$(($(date +%s)-T))"
echo "execution time (secs) ${T}"

Sin embargo, cuando intento esto:

T="$(date +%s%N)"
#some work here
T="$(($(date +%s%N)-T))"

Al agregar% N (como arriba) a la fecha para obtener la precisión de nanosegundos, aparece el siguiente error: -bash: 1369320760N: valor demasiado grande para la base (el token de error es "1369320760N")

¿Alguien sabe cómo medir el tiempo de ejecución en milisegundos usando bash en Mac OS X?

pacodelumberg
fuente
¿Realmente necesitas una resolución de nano segundos? Lo que este enfoque tiene un montón de gastos generales. Con # some work hereomitido, obtengo tiempos de 0.2 a 0.3 segundos, lo que debería ser cero (o al menos constante) para alcanzar su objetivo. Mientras que /usr/bin/time usleep 50000da un tiempo estable razonable de 0.05 +/- 0.01 seg. (Solo probado en Linux, no sé si / usr / bin / time y / o usleep están disponibles en OSX.)
mpy
¿Está seguro de que la resolución del reloj interno ofrece una resolución EXACTA hasta el nivel de nano segundos?
mdpc

Respuestas:

14

Dado que OSX es un sistema BSD-ish, su biblioteca de strftime no tiene %N( http://www.freebsd.org/cgi/man.cgi?query=date )

¿El timecomando bash builtin te da la información que necesitas?

time some work here
Glenn Jackman
fuente
2
gracias por dejarlo claro, el tiempo funciona perfectamente y genera tres resultados, pero necesito trabajar específicamente con los tiempos inicial y final.
pacodelumberg
11

Iría por esta ruta si necesitara milisegundos y BSD no admitiera la fecha +%s%N

perl -MTime::HiRes -e 'printf("%.0f\n",Time::HiRes::time()*1000)'
hpavc
fuente
¡¡¡Gracias!!! Esa es la solución de la que nadie informaba ...
Daniele B
3

echo $(($(date +%s%N)/1000000))

Esto convertiría de nano-segundos a milisegundos.

De @mpy, date +%s.%Nfunciona.

Sin embargo, la salida es diferente entre Linux y OS X:
Linux: 1369322592.573787111
OS X:1369322610.N

recatado
fuente
Recibo el siguiente error: -bash: 1369321446N: valor demasiado grande para la base (el token de error es "1369321446N") esto no funciona en mac osx, obtengo:
pacodelumberg
Bueno, eso es molesto ... (probado en una ventana incorrecta) viendo el mismo error: /
recatada
1
No es necesario dividir la salida, solo use date +%s.%N(pero no puedo verificar OSX; está funcionando en Linux). Pero el problema es que bash, en $(( ))mi humilde opinión, no puede manejar números de punto flotante.
mpy
@mpy Eso funciona en osx. Lo mismo para los primeros 10 caracteres, aunque actúa de manera diferente entre Linux y OS X.
recatada
¿Eso significa que no podemos obtener la información del nano segundo usando la fecha?
pacodelumberg
3

Si lo instala coreutils, puede usar GNU Linux dateescribiendo gdate.

coreutils está disponible con Homebrew: brew install coreutils.

youyoup
fuente
1

Como se menciona en la otra respuesta, la fecha de OS X no admite% N (nanosegundos).

¿Podrías guardar los comandos a tiempo como un script? O use un subshell o grupo de comando para ellos:

time (sleep 0.1; echo a; sleep 0.1)
time { sleep 0.1; echo a; sleep 0.1; }

O suma los tiempos de los comandos individuales:

$ time=$(TIMEFORMAT=%R; (time sleep 0.1; echo a) 2>&1 > /dev/null)
$ time+=+$(TIMEFORMAT=%R; (time sleep 0.1) 2>&1)
$ bc <<< $time
.206

O use un lenguaje de script:

$ ruby -e 'puts "%.3f" % Time.now'
1369329611.046
$ time ruby -e '""'
0.029
$ time ruby -e 'puts "%.3f" % Time.now'
1369329622.943
0.029

%.3fes un especificador de formato para un número de coma flotante con 3 puntos decimales. Time.now es un método de clase de la clase Time.

Lri
fuente
Gracias por su respuesta, ¿podría describir el código ruby ​​anterior?
pacodelumberg
1
En ruby -e 'puts "%.3f" % Time.now', rubyllama al intérprete de ruby, -eejecuta el script que sigue en la línea de comando. putses ruby printf(más o menos), Timees un objeto ruby ​​y Time.nowson los segundos desde la época. El uso %.3frecorta la salida a 3 decimales, que es milisegundos (las partes ".046" y ".943" de la salida.)
Olie
1
Además, timees una herramienta de línea de comandos que mide el tiempo que se tarda en ejecutar el comando que sigue. Ver man timepara más detalles.
Olie
1

Glenn tiene razón, timees el comando que está buscando, pero para analizar la información que desea, deberá pasarla a algún otro procesador como sed.

time command-goes-here >/dev/null 2>$1|sed rules-go-here

Este comando eliminará la salida del comando en sí mismo (enviando salidas estándar y de error a / dev / null), y pasará los resultados de tiempo a sed, donde deberá elegir las reglas apropiadas para editar la secuencia y la salida El valor deseado.

Zach Melnick
fuente