How do I get elapsed time in milliseconds in Ruby?

Ruby

Ruby Problem Overview


If I have a Time object got from :

Time.now

and later I instantiate another object with that same line, how can I see how many milliseconds have passed? The second object may be created that same minute, over the next minutes or even hours.

Ruby Solutions


Solution 1 - Ruby

As stated already, you can operate on Time objects as if they were numeric (or floating point) values. These operations result in second resolution which can easily be converted.

For example:

def time_diff_milli(start, finish)
   (finish - start) * 1000.0
end

t1 = Time.now
# arbitrary elapsed time
t2 = Time.now

msecs = time_diff_milli t1, t2

You will need to decide whether to truncate that or not.

Solution 2 - Ruby

You can add a little syntax sugar to the above solution with the following:

class Time
  def to_ms
    (self.to_f * 1000.0).to_i
  end
end

start_time = Time.now
sleep(3)
end_time = Time.now
elapsed_time = end_time.to_ms - start_time.to_ms  # => 3004

Solution 3 - Ruby

I think the answer is incorrectly chosen, that method gives seconds, not milliseconds.

t = Time.now.t­o_f
=> 1382471965.146

Here I suppose the floating value are the milliseconds

Solution 4 - Ruby

DateTime.now.strftime("%Q")

Example usage:

>> DateTime.now.strftime("%Q")
=> "1541433332357"

>> DateTime.now.strftime("%Q").to_i
=> 1541433332357

Solution 5 - Ruby

To get time in milliseconds, it's better to add .round(3), so it will be more accurate in some cases:

puts Time.now.to_f # => 1453402722.577573

(Time.now.to_f.round(3)*1000).to_i  # => 1453402722578

Solution 6 - Ruby

ezpz's answer is almost perfect, but I hope I can add a little more.

Geo asked about time in milliseconds; this sounds like an integer quantity, and I wouldn't take the detour through floating-point land. Thus my approach would be:

t8 = Time.now
# => Sun Nov 01 15:18:04 +0100 2009
t9 = Time.now
# => Sun Nov 01 15:18:18 +0100 2009
dif = t9 - t8
# => 13.940166
(1000 * dif).to_i
# => 13940

Multiplying by an integer 1000 preserves the fractional number perfectly and may be a little faster too.

If you're dealing with dates and times, you may need to use the DateTime class. This works similarly but the conversion factor is 24 * 3600 * 1000 = 86400000 .

I've found DateTime's strptime and strftime functions invaluable in parsing and formatting date/time strings (e.g. to/from logs). What comes in handy to know is:

  • The formatting characters for these functions (%H, %M, %S, ...) are almost the same as for the C functions found on any Unix/Linux system; and

  • There are a few more: In particular, %L does milliseconds!

Solution 7 - Ruby

%L gives milliseconds in ruby

require 'time'
puts Time.now.strftime("%Y-%m-%dT%H:%M:%S.%L")

or

puts Time.now.strftime("%Y-%m-%d %H:%M:%S.%L")

will give you current timestamp in milliseconds.

Solution 8 - Ruby

The answer is something like:

t_start = Time.now
# time-consuming operation
t_end = Time.now

milliseconds = (t_start - t_end) * 1000.0

However, the Time.now approach risks to be inaccurate. I found this post by Luca Guidi:

https://blog.dnsimple.com/2018/03/elapsed-time-with-ruby-the-right-way/

> system clock is constantly floating and it doesn't move only forwards. If your calculation of elapsed time is based on it, you're very likely to run into calculation errors or even outages.

So, it is recommended to use Process.clock_gettime instead. Something like:

def measure_time
  start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  yield
  end_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
  elapsed_time = end_time - start_time
  elapsed_time.round(3)
end

Example:

elapsed = measure_time do
    # your time-consuming task here:
    sleep 2.2321
end

=> 2.232

Solution 9 - Ruby

Time.now.to_f can help you but it returns seconds.

In general, when working with benchmarks I:

  • put in variable the current time;
  • insert the block to test;
  • put in a variable the current time, subtracting the preceding current-time value;

It's a very simple process, so I'm not sure you were really asking this...

Solution 10 - Ruby

Try subtracting the first Time.now from the second. Like so:

a = Time.now
sleep(3)
puts Time.now - a # about 3.0

This gives you a floating-point number of the seconds between the two times (and with that, the milliseconds).

Solution 11 - Ruby

If you want something precise, unaffected by other part of your app (Timecop) or other programs (like NTP), use Process#clock_gettime with Process::CLOCK_MONOTONIC to directly get the processor time.

t1 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
# other code
t2 = Process.clock_gettime(Process::CLOCK_MONOTONIC)

Also, if you are trying to benchmark some code tho, there is the Benchmark module for that!

require "benchmark"

time = Benchmark.realtime do
  # code to measure
end

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGeoView Question on Stackoverflow
Solution 1 - RubyezpzView Answer on Stackoverflow
Solution 2 - RubyphlipperView Answer on Stackoverflow
Solution 3 - RubyLowFieldTheoryView Answer on Stackoverflow
Solution 4 - RubyRyan McGearyView Answer on Stackoverflow
Solution 5 - RubySteven YueView Answer on Stackoverflow
Solution 6 - RubyCarl SmotriczView Answer on Stackoverflow
Solution 7 - RubySandeep Singh NagraView Answer on Stackoverflow
Solution 8 - RubyRobertView Answer on Stackoverflow
Solution 9 - RubyvygerView Answer on Stackoverflow
Solution 10 - RubymruegView Answer on Stackoverflow
Solution 11 - RubyCapripotView Answer on Stackoverflow