我注意到当
time.monotonic_ns
和 time.sleep
在很短的时间内相互作用时,会出现一些奇怪的行为。
为了调查这一点,我编写了以下“测试”。
import time
def main():
while True:
start = time.monotonic_ns()
time.sleep(0.01) # 10 milliseconds
end = time.monotonic_ns()
diff = end - start
print("diff: {}".format(diff))
if __name__ == "__main__":
main()
此代码大多数情况下会打印大约
15000000
(实际上正好是 15000000 ns 或 16000000 ns)或 15
毫秒的值,但有时只是 0
。
如果我进一步减少睡眠时间,它会具有完全相同的行为(即 15 毫秒或 0 纳秒)。
当我使用
time.time_ns
时,它每次都会非零(也更加随机,有时甚至会下降到 ~11 毫秒),time.perf_counter_ns
也可以正常工作。我知道 time.process_time
将始终为 0,因为它不计算睡眠时间。 timeit.timit
还显示我的系统上的最小睡眠时间约为 8 毫秒。
我使用的是 Windows 11 设备。根据 python 时间文档,睡眠的分辨率为 100 纳秒(显然小于 10 毫秒)。对于
time.monotonic_ms()
,我无法找到解决方案。
我可以理解它怎么会超过指定的 10 毫秒,但我不知道它怎么会是 0 纳秒。 Python 版本:3.9.13.
我也在 3.12 上对此进行了测试,唯一的区别是当我尝试使用 CTRLC 停止执行时 IDLE 会冻结。
我通过对此答案的评论(根据用户“deceze ♦”此处的评论通过“链接跳跃”发现)知道了一个名为
time.get_clock_info
的函数。此函数提供多个时钟的时钟信息(在时间模块中)。
这是
time
的输出:
namespace(implementation='GetSystemTimeAsFileTime()', monotonic=False, adjustable=True, resolution=0.015625)
可以看出,正如我之前看到的,分辨率约为 16 毫秒。 显然
monotonic
是 monotonic_ns
的计时器(一般来说,所有 ..._ns
计时器看起来只是非 ns 版本的专门变体)具有相同的分辨率(具有不同的基数):
namespace(implementation='GetTickCount64()', monotonic=True, adjustable=False, resolution=0.015625)
这仍然没有给出为什么它有时为零的答案。
perf_counter
具有更高的精度:
namespace(implementation='QueryPerformanceCounter()', monotonic=True, adjustable=False, resolution=1e-07)
process_time
与 perf_counter
具有相同的精度:
namespace(implementation='GetProcessTimes()', monotonic=True, adjustable=False, resolution=1e-07)
Python:Windows 11 Home 上的 3.9.13(Windows 版本似乎有所不同)