Thoughts about tech, programming, and more.

Measuring elapsed time with Ruby

Over the weekend I was working on a side project and I found myself needing to improve the speed of certain methods, so looked up some ways to measure time in Ruby for this purpose.

Several posts gave the obvious answer - set a start_time variable at start, set an end_time variable at end and calculate the difference. Easy. But not necessarily the best answer.

The problem with that approach, which Luca Guidi in this blog post nicely spells out, is that Time.now gets the current time from the system, but the system is not meant for measuring duration.

The reason for this is that system time is constantly re-syncing and adjusting its time to stay the correct clock time, which means that the system time can change both forward and backwards if it becomes out of sync and needs to correct itself. That means that system time is not an accurate method for measuring elapsed time. Especially when it comes to measuring elapsed time in small units of time like milliseconds.

The Better Way

There is another approach that avoids the issues mentioned above. It uses the Monotonic Clock.

The Monotonic Clock behaves similarly to how a stopwatch or timer would behave. It doesn't concern itself with staying in sync with any external world clock, but only with the elapsed time since the last Mac OS boot.

That means that we can measure elapsed time accurately in Ruby like this:

starting = Process.clock_gettime(Process::CLOCK_MONOTONIC)
   
# process that you're measuring
    
ending = Process.clock_gettime(Process::CLOCK_MONOTONIC)
elapsed = ending - starting
elapsed # => 5.702740999986418 (seconds)

Subscribe to Daniel Lemky

Sign up now to get access to the library of members-only issues.
Jamie Larson
Subscribe