Как выполнить операцию в миллисекундах в Ruby?
Я хочу выяснить, сколько миллисекунд использует определенная функция. Поэтому я выглядел высоко и низко, но не смог найти способ получить время в Ruby с точностью до миллисекунды.
Как вы это делаете? В большинстве языков программирования это просто что-то вроде
start = now.milliseconds
myfunction()
end = now.milliseconds
time = end - start
Ответы
Ответ 1
Вы можете использовать класс ruby Time
. Например:
t1 = Time.now
# processing...
t2 = Time.now
delta = t2 - t1 # in seconds
Теперь delta
является объектом float
, и вы можете получить как мелкое зерно результат, как будет предоставлен класс.
Ответ 2
Вы также можете использовать встроенную функцию Benchmark.measure:
require "benchmark"
puts(Benchmark.measure { sleep 0.5 })
Печать
0.000000 0.000000 0.000000 ( 0.501134)
Ответ 3
Вы должны взглянуть на эталонный модуль для выполнения тестов. Однако, как быстрый и грязный метод синхронизации, вы можете использовать что-то вроде этого:
def time
now = Time.now.to_f
yield
endd = Time.now.to_f
endd - now
end
Обратите внимание на использование Time.now.to_f
, которое в отличие от to_i не будет усекать до нескольких секунд.
Ответ 4
Использовать Time.now.to_f
Ответ 5
Драйвер absolute_time
- это замена замены для Benchmark, но использование нативных инструкций является гораздо более точным.
Ответ 6
Использование Time.now
(которое возвращает время настенных часов), поскольку базовые линии имеют пару проблем, которые могут привести к неожиданному поведению. Это вызвано тем фактом, что время настенного тока может быть изменено, например, вставленные прыжки-секунды или время поворота, чтобы настроить местное время на ссылку время.
Если есть, например, вторая секунда, вставленная во время измерения, будет отключена на секунду. Точно так же, в зависимости от локальных системных условий, вам, возможно, придется иметь дело с дневным временем, быстрыми или медленными работающими часами или часами, даже перескакивая назад во времени, что приводит к отрицательной продолжительности и многим другим проблемам.
Решение этой проблемы - использовать другое время: монотонные часы. Этот тип часов имеет разные свойства, чем настенные часы.
Он увеличивается монотонно, т.е. Никогда не возвращается и увеличивается с постоянной скоростью. При этом он не представляет собой настенные часы (т.е. Время, которое вы читаете из часов на стене), но временную метку, которую вы можете сравнить с более поздней меткой времени, чтобы получить разницу.
В Ruby вы можете использовать такую метку времени с Process.clock_gettime(Process::CLOCK_MONOTONIC)
следующим образом:
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
Метод Process.clock_gettime
возвращает метку времени как float с дробными секундами. Возвращаемое фактическое число не имеет определенного значения (на которое вы должны положиться). Тем не менее, вы можете быть уверены, что следующий вызов вернет большее число, и, сравнив значения, вы можете получить разницу в реальном времени.
Эти атрибуты делают метод основным кандидатом для измерения разницы во времени, не видя, что ваша программа завершилась неудачей в наименее подходящее время (например, в полночь в канун Нового года, когда вставлена другая вставка).
Ответ 7
Использование Time.now.to_i
возвращает второе, прошедшее с 1970/01/01. Зная это, вы можете сделать
date1 = Time.now.to_f
date2 = Time.now.to_f
diff = date2 - date1
При этом у вас будет разница во второй. Если вы хотите в миллисекундах, просто добавьте в код
diff = diff * 1000
Ответ 8
Если вы используете
date = Time.now.to_i
Вы получаете время в секундах, что далеко не точно, особенно если вы синхронизируете небольшие фрагменты кода.
Ответ 9
У меня есть драгоценный камень, который может профилировать ваш метод ruby (экземпляр или класс) - https://github.com/igorkasyanchuk/benchmark_methods.
Больше нет кода:
t = Time.now
user.calculate_report
puts Time.now - t
Теперь вы можете сделать:
benchmark :calculate_report # in class
И просто вызовите ваш метод
user.calculate_report