time.get_clock_info().resolution 的含义

Meaning of time.get_clock_info().resolution

pythontime模块提供五种时钟:timemonotonicperf_counterprocess_timethread_time(以及已弃用的 clock)。 documentation 中很好地解释了这些时钟的作用。

您可以使用 time.get_clock_info(<clock_name>) 函数获取有关这些时钟的系统相关信息。这特别是 returns 这个时钟的 resolution,在我的理解中,连续调用那个时钟之间的最小差异不为零。为了对此进行测试,我创建了以下代码:

import time

names = ['time', 'monotonic', 'perf_counter', 'process_time', 'thread_time']

for n in names:
    info = time.get_clock_info(n)
    f = getattr(time, n)
    print(n, info)
    l = []
    for _ in range(1000000):
        l.append(f())
    deltas = [l[i] - l[i - 1] for i in range(1, len(l)) if l[i] - l[i - 1] != 0]
    print(min(deltas, default=0))

此代码为我打印以下内容:

time 0.015625
0.00650477409362793
monotonic 0.015625
0.015000000013969839
perf_counter 3.77580764525532e-07
3.7699999988483057e-07
process_time 1e-07
0.015625
thread_time 1e-07
0.015625

这非常令人惊讶,因为 time 的实际最小增量比承诺的小 2.4 倍,而 process_timethread_time 的实际最小增量都比承诺的大 150.000 倍答应了。

这是为什么?该实施是否取决于并且 python 不知道实际的分辨率?如果是这样,它为什么要假装知道?还是我误会了什么?

系统信息:

“比承诺大 150.000 倍”的值完全没问题。您的代码的执行将需要一些时间。您得到的承诺是,这是您可以注册的最小差异,而不是 2 个连续调用将获得该值。此外,这是计时器中值的分辨率,而不是计时器本身。您可以有一个以 100 ns 为增量计数的计时器,但实际上每 1us 添加 10 个。

对于另一种方式:您可以按照 "time" 实现 windows 到 pygettimeofday (which uses GetSystemTimeAdjustment)。您必须深入研究这些描述以查看结果。一个有趣的地方是 lpTimeIncrement 显然只在设置了 lpTimeAdjustmentDisabled 的情况下才重要——而这是 cpython 不检查的东西。

perf_counter 很奇怪,不太可能是正确的。它从 QueryPerformanceCounter 中获取值,但在 377ns 内执行时间测量的可能性很小。

为了更好地了解计时器的行为方式,您还可以绘制结果的直方图而不是使用最小值。