tags:

views:

47

answers:

2

I have this trial timer code to time euler solutions in Ruby.

$RUNS = 12
def run(solve)
  times = []
  $RUNS.times do
    start_t = Time.now.usec
    solve.call
    end_t = Time.now.usec
    times << (end_t - start_t)/1000.0
  end
  #times = times.delete_if {|i| i < 0}
  puts times.inspect
  times.sort

  mean = times.inject{|a,c| a+c} / $RUNS
  puts("Mean:\t#{mean}");
  if (times.length % 2 == 0) then
    median = (times[times.length / 2 - 1] + times[times.length / 2]) / 2.0
  else 
    median = times[times.length / 2];
  end
  puts("Median: #{median}");

end

Unfortunately, I keep getting answers like this:

[409.805, 418.16, -582.23, 402.223, -581.94, 413.196, 426.816, -584.732, 519.457, -569.557, 558.918, -579.176]

What can I do to avoid these strange negative numbers?

+2  A: 

usec returns the microseconds from the time in the same was as month returns the month. It is not the number of microseconds for the given time since the epoch.

So if start_t was 1049896564.259970 seconds and end_t was 1049896592.123130 seconds then you would get 123130 - 259970 if you subtracted the usecs. i.e. a negative number.

Instead you could use Time.now.to_f to convert to floating point number of seconds since epoch and subtract those from each other. You can also just subtract one Time object from another directly e.g.

start_t = Time.now
solve.call
end_t = Time.now
times << end_t - start_t
mikej
Then how do I do high-granularity timing in ruby?
JBristow
@JBristow Answer updated with a suggestion of how to do what you want.
mikej
It seems like this is asking for floating point errors, but I am multiplying by 1000 to get msec granularity.
JBristow
You should also take a look at [benchmark](http://ruby-doc.org/stdlib/libdoc/benchmark/rdoc/index.html) in the standard library, although if you look at the source for that I think it still just uses `to_f` when calculating time deltas.
mikej
A: 

Current time in seconds since the Epoch:

Time.now.to_f
=> 1278631398.143

That should have microsecond resolution, despite only three decimal places being shown here.

bta