正确测量Go的持续时间 [英] Correctly measure time duration in Go

查看:209
本文介绍了正确测量Go的持续时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

然而, time.Now()会返回当前系统时间,这会导致两个缺陷:


  1. 如果系统时间在测量过程中发生变化(例如由于时区变化(DST)或闰秒<由此产生的持续时间也是错误的。

  2. 系统时间可以刻意快于或慢于实时。当操作系统将内部时钟与NTP时间服务器同步时(这种情况可能每小时发生几次!),总会发生这种情况。

    From MSDN


    [时间服务]调整本地时钟速率,使其
    收敛到正确的时间。如果
    本地时钟与[精确时间采样]之间的时间差太大而无法通过调整本地时钟频率
    进行校正,则时间服务会将本地时钟
    设置为正确的时间。


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

因此,大多数其他语言都提供了一个专门用于测量持续时间的API:


  • Java有 System.nanoTime() System.currentTimeMillis()会相当于 time.Now()并且是错误的

  • C#有 System.Diagnostics.Stopwatch

  • Windows上的C / C ++具有 QueryPerformanceCounter QueryPerformanceFrequency

  • C ++ 11及更高版本具有 std :: chrono :: steady_clock std :: chrono :: high_resolution_clock is_steady 成员常量是 true

  • JavaScript有 performance.now() ,而使用 new Date()错误



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



    单调时钟

    操作系统同时提供挂钟,它受时钟同步的
    变化和一个单调时钟的影响,它不是
    。一般的规则是,挂钟是用来告诉时间的,
    是单调时钟用于测量时间的。而不是分割API,在这个包中的
    ,time.Now返回的时间包含一个
    的时钟读数和一个单调的时钟读数;以后的时间告诉
    操作使用挂钟读数,但后来计时
    操作,特别是比较和减法,使用
    单调时钟读数。

    例如,即使在定时操作过程中挂钟更改为
    ,该代码始终会计算大约20毫秒的正常过期时间


      start:= time.Now()
    ...需要20毫秒的操作...
    t:= time.Now )
    过去了:= t.Sub(开始)

    其他成语,如时间。自(开始)以来,time.Until(截止日期)和
    time.Now()。在截止日期之前,对墙上时钟
    重置也是类似的。
    blockquote>

    从Go 1.9开始(2017年8月24日发布),Go使用单调时钟持续时间。 a href =https://golang.org/design/12914-monotonic =noreferrer>建议:单调经过时间测量在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?

    解决方案

    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.

    这篇关于正确测量Go的持续时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆