4

pythontime模块提供五个时钟:timemonotonicperf_counterprocess_timethread_time(以及已弃用的clock)。这些时钟的作用在文档中有很好的解释。

您可以使用该功能获取有关这些时钟的系统相关信息time.get_clock_info(<clock_name>)。这尤其会返回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

这非常令人惊讶,因为 的实际最小 deltatime比承诺的小 2.4 倍,而 和 的实际最小 deltaprocess_time都比thread_time承诺的大 150.000 倍。

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

系统信息:

  • 视窗 10 64 位
  • Python3.7 64位
4

1 回答 1

2

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

对于另一种方式:您可以按照窗口的“时间”实现到pygettimeofday(使用GetSystemTimeAdjustment)您必须深入研究这些描述以查看结果。一个有趣的一点是,lpTimeIncrement显然只有lpTimeAdjustmentDisabled设置才重要——这是 cpython 不检查的东西。

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

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

于 2018-07-18T01:52:11.437 回答