Correctly measure time duration in Go

前端 未结 3 1886
有刺的猬
有刺的猬 2020-12-17 08:39

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 start         


        
相关标签:
3条回答
  • 2020-12-17 08:52

    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.

    0 讨论(0)
  • 2020-12-17 08:53

    For Go 1.8 and before, the correct timing function is not inside the time package, but instead in the runtime package:

    func nanotime() int64
    

    In order to correctly measure execution time, the following procedure should be used:

    var startTime = runtime.nanotime()
    doSomeHardWork()
    var duration = runtime.nanotime() - startTime
    

    Unfortunately, the method itself is not documented very well. It emerged in this issue after a long discussion if it was really neccessary. For Go 1.9 and newer, refer to Kenny Grant's answer.

    0 讨论(0)
  • 2020-12-17 09:07

    This is available in Go 1.9 (August 2017) with monotonic clocks, you won't have to do anything special to benefit from it:

    https://tip.golang.org/pkg/time/#hdr-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.

    This change to the time pkg was triggered by this issue, which prompted this proposal for change from Russ Cox:

    Comparison and subtraction of times observed by time.Now can return incorrect results if the system wall clock is reset between the two observations. We propose to extend the time.Time representation to hold an additional monotonic clock reading for use in those calculations. Among other benefits, this should make it impossible for a basic elapsed time measurement using time.Now and time.Since to report a negative duration or other result not grounded in reality.

    0 讨论(0)
提交回复
热议问题