Go - Measuring Lapsed Time

发布时间 2023-10-06 12:30:11作者: ZhangZhihuiAAA

Problem: You want to measure the lapsed time and make sure that it is accurate.


Solution: Use the monotonic clock in the Time struct to find the lapsed time.

 

The Time struct contains the data but only under certain circumstances. If you create a Time struct instance using time.Now , and print out the struct, you will be able to see the monotonic clock:

t   :=   time . Now () 
fmt . Println ( t )

When you run it you see this:

2021 - 10 - 09  13:10:43.311791  +0800  +08  m=+0.000093742

The m=+0.000093742 part is the monotonic clock. The part before that is the wall clock. This is what the package documentation says:
If the time has a monotonic clock reading, the returned string includes a final field “m=±<value>”, where value is the monotonic clock reading formatted as a decimal number of seconds.
But what does it mean by the monotonic clock reading formatted as a decimal number of seconds ? It’s a really small number! Actually, this just shows how long your program has been running.

func   main ()   { 
      time . Sleep ( 10   *   time . Second )   //  pretend  to  do  something  for  10s 
      t1   :=   time . Now () 
      t2   :=   time . Now () 
      fmt . Println ( "t1:" ,   t1 ) 
      fmt . Println ( "t2:" ,   t2 ) 
      fmt . Println ( "difference:" ,   t2 . Sub ( t1 )) 
}

This is what you should see after 10 seconds:

t1:  2021 - 10 - 09  15:12:12.432516  +0800  +08  m=+10.005330678
t2:  2021 - 10 - 09  15:12:12.432516  +0800  +08  m=+10.005330984
difference:  306ns

The interesting point to note here is that if you use the wall clock, you won’t be able to tell the difference at all!

As noted earlier, the monotonic clock data is not always available in the Time struct. Methods such as AddDate , Round , and Truncate are wall clock computations so the Time structs they return won’t have the monotonic clock. Similarly, In , Local , and UTC interpret the wall clock, so the Time structs they return won’t have the monotonic clock either.

You can also remove the monotonic clock yourself. Just use the Round method with a 0 parameter:

t   :=   time . Now (). Round ( 0 ) 
fmt . Println ( t )

You should get something like this:

2021 - 10 - 09  15:25:31.369518  +0800  +08

You no longer see the monotonic clock here. So what happens when you try to call Sub (or any other monotonic methods) on a Time struct instance that doesn’t have the monotonic clock?

func   main ()   { 
      t1   :=   time . Now (). Round ( 0 ) 
      t2   :=   time . Now (). Round ( 0 ) 
      fmt . Println ( "t1:" ,   t1 ) 
      fmt . Println ( "t2:" ,   t2 ) 
      fmt . Println ( "difference:" ,   t2 . Sub ( t1 )) 
}

Now t1 and t2 have their monotonic clocks stripped away. If you try to find the difference between these two times, you will get a big fat 0. This is because the operation will be done on the wall clock instead of the monotonic clock, and the wall clock just isn’t fine - grained enough:

t1:  2021 - 10 - 09  15:28:38.451622  +0800  +08
t2:  2021 - 10 - 09  15:28:38.451622  +0800  +08
difference:  0s