¿Cómo sincronizar una operación en milisegundos en Ruby?
timer (9)
Debería echar un vistazo al módulo de referencia para realizar puntos de referencia. Sin embargo, como un método de temporización rápido y sucio puede usar algo como esto:
def time
now = Time.now.to_f
yield
endd = Time.now.to_f
endd - now
end
Tenga en cuenta el uso de Time.now.to_f
, que a diferencia de to_i, no se truncará en segundos.
Estoy deseando saber cuántos milisegundos usa una función en particular. Así que miré alto y bajo, pero no pude encontrar la manera de pasar el tiempo en Ruby con una precisión de milisegundos.
¿Cómo haces esto? En la mayoría de los lenguajes de programación es algo así como
start = now.milliseconds
myfunction()
end = now.milliseconds
time = end - start
El uso de Time.now.to_i
devuelve el segundo aprobado desde 1970/01/01. Sabiendo esto, puedes hacer
date1 = Time.now.to_f
date2 = Time.now.to_f
diff = date2 - date1
Con esto tendrás diferencia en segunda magnitud. Si lo quiere en milisegundos , simplemente agregue al código
diff = diff * 1000
La gema absolute_time
es un reemplazo directo para Benchmark, pero usa instrucciones nativas para ser mucho más preciso.
Puedes usar la clase de Time
de ruby. Por ejemplo:
t1 = Time.now
# processing...
t2 = Time.now
delta = t2 - t1 # in seconds
Ahora, delta
es un objeto float
y puede obtener un resultado tan fino como la clase proporcionará.
Si utiliza
date = Time.now.to_i
Estás obteniendo tiempo en segundos, eso está lejos de ser preciso, especialmente si estás cronometrando pequeños trozos de código.
También puede usar la función incorporada Benchmark.measure:
require "benchmark"
puts(Benchmark.measure { sleep 0.5 })
Huellas dactilares:
0.000000 0.000000 0.000000 ( 0.501134)
Tengo una gema que puede perfilar su método Ruby (instancia o clase) - https://github.com/igorkasyanchuk/benchmark_methods .
No más códigos como este:
t = Time.now
user.calculate_report
puts Time.now - t
Ahora puedes hacer:
benchmark :calculate_report # in class
Y solo llame a su método
user.calculate_report
Usar Time.now
(que devuelve la hora del reloj de pared) como líneas base tiene un par de problemas que pueden provocar un comportamiento inesperado. Esto se debe al hecho de que el tiempo de reloj de pared está sujeto a cambios como segundos intercalares insertados o giro de tiempo para ajustar la hora local a un tiempo de referencia.
Si hay, por ejemplo, un segundo intercalar insertado durante la medición, se desactivará por un segundo. Del mismo modo, dependiendo de las condiciones del sistema local, es posible que tenga que lidiar con los horarios de ahorro de energía, los relojes que corren más rápido o más lento, o que el reloj retroceda en el tiempo, lo que da como resultado una duración negativa y muchos otros problemas.
Una solución a este problema es usar un reloj diferente: un reloj monótono. Este tipo de reloj tiene diferentes propiedades que el reloj de pared. Se incrementa monitonicamente, es decir, nunca retrocede y aumenta a una velocidad constante. Con eso, no representa el reloj de pared (es decir, el tiempo que lees de un reloj en tu pared), sino una marca de tiempo que puedes comparar con una marca de tiempo posterior para obtener una diferencia.
En Ruby, puede usar dicha marca de tiempo con Process.clock_gettime(Process::CLOCK_MONOTONIC)
siguiente manera:
t1 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
# => 63988.576809828
sleep 1.5 # do some work
t2 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
# => 63990.08359163
delta = t2 - t1
# => 1.5067818019961123
delta_in_milliseconds = delta * 1000
# => 1506.7818019961123
El método Process.clock_gettime
devuelve una marca de tiempo como un flotante con segundos fraccionarios. El número real devuelto no tiene un significado definido (en el que debe confiar). Sin embargo, puede estar seguro de que la próxima llamada devolverá un número mayor y al comparar los valores, puede obtener la diferencia de tiempo real.
Estos atributos hacen que el método sea un candidato ideal para medir las diferencias de tiempo sin ver su programa fallar en los momentos menos oportunos (por ejemplo, a la medianoche en la víspera de Año Nuevo cuando se inserta otro segundo intercalar).
Use Time.now.to_f