drl47263 2017-08-21 07:13
浏览 83
已采纳

在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:

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

  • 写回答

3条回答 默认 最新

  • douweng3564 2017-08-21 07:21
    关注

    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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突
  • ¥15 超声波模块测距控制点灯,灯的闪烁很不稳定,经过调试发现测的距离偏大
  • ¥15 import arcpy出现importing _arcgisscripting 找不到相关程序