在不受时钟变化影响的情况下计时一个操作。

huangapple go评论85阅读模式
英文:

Timing an operation without being affected by clock changes

问题

我正在寻找:

1: startTime := time.Now()

2: // 在这里运行需要一段时间的代码(以毫秒为单位)

3: duration := time.Since(startTime)

然而,我需要一种不受时钟时间更改影响的方法。如果在第1行和第3行之间调整了时间,那么持续时间将不准确。

解决这个问题的一些常见方法是什么,有哪些相关的Go库可以使用?

谢谢 在不受时钟变化影响的情况下计时一个操作。

英文:

I'm looking for:

1: startTime := time.Now()

2: // run something here that takes a while (measured in milliseconds)

3: duration := time.Since(startTime)

However, I need something that is immune to clock time changes. If the time is adjusted between lines 1 and 3, the duration will be inaccurate.

What are some common approaches for solving this problem, and what Go libraries could be relevant?

Thanks 在不受时钟变化影响的情况下计时一个操作。

答案1

得分: 2

对于Linux(AMD64),Go使用clock_gettimeCLOCK_REALTIME。请参阅time·now的实现

你可能需要一个单调时钟(CLOCK_MONOTONICCLOCK_MONOTONIC_RAW),它是一个不会倒退的时钟。在Linux中,man页面明确告诉你CLOCK_MONOTONIC不能保证不会向前跳跃:

> 这个时钟不受系统时间的不连续跳跃的影响(例如,如果系统管理员手动更改时钟),但会受到adjtime(3)和NTP执行的增量调整的影响。

因此,在Linux下,最好的选择可能是CLOCK_MONOTONIC_RAW。你可以使用clock包来实现。示例代码如下:

import (
    "fmt"
    "github.com/davecheney/junk/clock"
    "time"
)

func main() {
    start := clock.Monotonic.Now()
    // 工作
    end := clock.Monotonic.Now()

    duration := end.Sub(start)

    fmt.Println("Elapsed:", duration)
}

进一步阅读:

英文:

For Linux (AMD64) go uses clock_gettime with CLOCK_REALTIME.
See the time·now implementation.

You would want a monotonic clock (CLOCK_MONOTONIC or CLOCK_MONOTONIC_RAW), which
is a clock that does not go back in time. In Linux the man page explicitly tells you that CLOCK_MONOTONIC does not guarantee to not leap forward:

> This clock is not affected by discontinuous jumps in the system time (e.g., if the system administrator
manually changes the clock), but is affected by the incremental adjustments performed by adjtime(3) and NTP.

So, under Linux, the best choice is probably CLOCK_MONOTONIC_RAW. You may use the
clock package mentioned by @MatrixFrog for that. Example:

import (
    "fmt"
    "github.com/davecheney/junk/clock"
    "time"
)

func main() {
    start := clock.Monotonic.Now()
    // work
    end := clock.Monotonic.Now()

    duration := end.Sub(start)

    fmt.Println("Elapsed:", duration)
}

Further reading:

答案2

得分: 2

缺乏单调时钟的问题在issue 12914(2015年)中有详细说明。

自那时以来,在2017年8月和Go 1.9中,现在已经有了透明的单调时间支持

time包现在在每个Time值中透明地跟踪单调时间,在存在壁钟调整的情况下,计算两个Time值之间的持续时间是安全的操作
有关详细信息,请参阅包文档设计文档

英文:

That lack of monotonic clock was detailed in issue 12914 (2015)

Since then, in August 2017 and Go 1.9, you now have a transparent Monotonic Time support:

> The time package now transparently tracks monotonic time in each Time value, making computing durations between two Time values a safe operation in the presence of wall clock adjustments.
See the package docs and design document for details.

huangapple
  • 本文由 发表于 2013年10月29日 09:02:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/19647856.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定