Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correctly measure time duration in Go

Tags:

time

go

What is the correct way to precisely measure a time duration in Go? Most application just use the standard time package and the following approach:

var startTime = time.Now() doSomeHardWork() var duration = time.Since(startTime) // or: time.Now() - startTime 

However, time.Now() returns the current system time, which leads to two flaws:

  1. If the system time is changed during the measurement (for example due to a time zone change (DST) or a leap second), the resulting duration is also wrong.
  2. The system time can tick deliberately faster or slower than the real time. This always happens when the operating system synchronizes the internal clock with NTP time servers (which might happen several times an hour!)

    From MSDN:

    [The time service] adjusts the local clock rate to allow it to converge toward the correct time. If the time difference between the local clock and the [accurate time sample] is too large to correct by adjusting the local clock rate, the time service sets the local clock to the correct time.

If the system time changes (either manually or due to DST), it might be possible to detect the invalid duration and discard it. But if the system clock ticks e.g. 10% faster to synchronize with world-time, it is practically impossible to detect. That's intended behaviour and how the system clock is designed.

For that reason, most other languages offer a dedicated API for measuring durations:

  • Java has System.nanoTime(), System.currentTimeMillis() would be equivalent to time.Now() and is wrong
  • C# has System.Diagnostics.Stopwatch
  • C/C++ on Windows has QueryPerformanceCounter and QueryPerformanceFrequency
  • C++11 and up have std::chrono::steady_clock, or std::chrono::high_resolution_clock when its is_steady member constant is true
  • JavaScript has performance.now(), while the use of new Date() is wrong

What is the correct way to precisely measure execution time in Go?

like image 783
maja Avatar asked Aug 21 '17 07:08

maja


People also ask

How do you measure time in go?

⏲️ Measure execution time in Go Before the function, you need to record the current time using time. Now() . Then, after executing the measured block, you can check how much time has elapsed since this time using time. Since() function.

What is time duration in Golang?

Golang == operator compares not only time instant but also the Location and the monotonic clock reading. time. Duration has a base type int64. Duration represents the elapsed time between two instants as an int64 nanosecond count”. The maximum possible nanosecond representation is up to 290 years.

What is the type of time duration?

time. Duration is a type having int64 as its underlying type, which stores the duration in nanoseconds. The above works because 100 is an untyped constant, and it can be converted automatically to time. Duration which has int64 underlying type.


1 Answers

Package time

Monotonic Clocks

Operating systems provide both a “wall clock,” which is subject to changes for clock synchronization, and a “monotonic clock,” which is not. The general rule is that the wall clock is for telling time and the monotonic clock is for measuring time. Rather than split the API, in this package the Time returned by time.Now contains both a wall clock reading and a monotonic clock reading; later time-telling operations use the wall clock reading, but later time-measuring operations, specifically comparisons and subtractions, use the monotonic clock reading.

For example, this code always computes a positive elapsed time of approximately 20 milliseconds, even if the wall clock is changed during the operation being timed:

start := time.Now() ... operation that takes 20 milliseconds ... t := time.Now() elapsed := t.Sub(start) 

Other idioms, such as time.Since(start), time.Until(deadline), and time.Now().Before(deadline), are similarly robust against wall clock resets.

Starting with Go 1.9 (released August 24, 2017), Go uses a monotonic clock for durations.

See Proposal: Monotonic Elapsed Time Measurements in Go.

like image 89
peterSO Avatar answered Sep 18 '22 22:09

peterSO