Use Time.monotonic to measure time in spawn not work as expected


I want to measure time which run a time-consuming process in spawn, following is reduced code which i use sleep to simulate the process time.

start_time = Time.monotonic

chan = Channel(Tuple(String, Int32)).new

def meth_4_seconds(chan, start_time)
  sleep 4
  chan.send({"method_4_seconds", (Time.monotonic - start_time).milliseconds})

def meth_2_seconds(chan, start_time)
  sleep 2
  chan.send({"meth_2_seconds", (Time.monotonic - start_time).milliseconds})

spawn meth_4_seconds(chan, start_time)
spawn meth_2_seconds(chan, start_time)

2.times do
  p chan.receive

The really confused me is, except for the time is incorrect, even, the method_2_seconds spent more time than method_4_seconds:

 ╰─ $ crystal build && ./1
{"meth_2_seconds", 2}
{"method_4_seconds", 1}

I guess i misunderstood the usage of something, how to fix that?


Time::Span#milliseconds returns only the sub-second fraction of the span, with millisecond precision.
If you want to the entire time expressed in milliseconds, you need to call Time::Span#total_milliseconds.

1 Like