go - 在 Go 中正确测量持续时间

标签 go time

在 Go 中精确测量持续时间的正确方法是什么? 大多数应用程序只是使用标准时间包和以下方法:

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

但是,time.Now()返回的是当前系统时间,这就导致了两个缺陷:

  1. 如果系统时间在测量过程中发生变化(例如由于时区变化 (DST) 或闰秒),则生成的持续时间也是错误的.
  2. 系统时间可以故意比实际时间快或慢。当操作系统将内部时钟与 NTP 时间服务器同步时,总是会发生这种情况(每小时可能会发生几次!)

    来自 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.

如果系统时间更改(手动或由于 DST),可能会检测到无效的持续时间并将其丢弃。但是如果系统时钟滴答作响,例如与世界时间同步速度快 10%,几乎无法检测到。这是预期的行为以及系统时钟的设计方式。

因此,大多数其他语言都提供专用 API 来测量持续时间:

在 Go 中精确测量执行时间的正确方法是什么?

最佳答案

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.

从 Go 1.9(2017 年 8 月 24 日发布)开始,Go 使用单调时钟来表示持续时间。

Proposal: Monotonic Elapsed Time Measurements in Go .

关于go - 在 Go 中正确测量持续时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45791241/

相关文章:

mongodb - 在嵌入式数组 golang 中检索范围时间 mongodb 之间的值

C++语句重新排序

ios-chart 值不会基于 x 和 y 轴 Swift 绘制

go - 如何在Visual Studio代码中允许“vendor ”文件夹支持

go - http.Hijacker 的返回值是什么?

go - 如何构建多语言存储库以与 golang 合理配合?

go - 从 "github.com/graphql-go/graphql"中的请求中获取查询名称

c++ - 为什么同一次执行的时间不同?

java - 如何将python时间转换为java日期

sql - 使 SQL INSERT 语句更易于阅读