为什么time.sleep()在Windows中这么慢?

时间:2016-11-14 17:33:48

标签: windows multithreading python-3.x

我循环1000次,延时1ms并计算总时间。非常有趣的是总时间是15.6秒而不是1.当我打开谷歌浏览器并浏览一些网站时,它总共运行1秒。此外,它也适用于Macbook。 我想知道我需要采取哪种解决方案才能解决这个问题?请尝试运行它,而无需再次打开Chrome,Chrome已打开以查看差异。当Quora或Reddit或Stackoverflow在我的系统上打开时,它正常运行。

from timeit import default_timer as timer
import time
start = timer()
for i in range(1000):
    time.sleep(0.001)

end = timer()
print ("Total time: ", end - start)

编辑:我没有在Python上运行它。我刚刚打开Chrome并浏览了一些网站,以加快时间延迟。

更新:它是关于Windows的计时器分辨率。基本上,Chrome将定时器分辨率从15.6ms更改为1ms。本文非常好地解释了:https://randomascii.wordpress.com/2013/07/08/windows-timer-resolution-megawatts-wasted/

1 个答案:

答案 0 :(得分:3)

我终于明白了。非常感谢您的评论。那些给了我解决它的提示。为了解释这种情况发生的原因,Windows操作系统将其默认计时器分辨率设置为15.625 ms或64 Hz,这对于大多数应用程序来说已经足够了。但是,对于需要非常短的采样率或时间延迟的应用,则15.625 ms是不够的。因此,当我自己运行程序时,它会在15.6秒内停留1000点。但是,当Chrome打开时,触发更高分辨率的计时器并更改为1毫秒而不是15毫秒,这导致我的程序按预期运行。

因此,为了解决这个问题,我需要调用名为timeBeginPeriod(period)的Windows函数来更改分辨率计时器。幸运的是,python让我很容易通过提供ctypes库来修复它。最终代码如下:

from time import perf_counter as timer
import time
from ctypes import windll #new

timeBeginPeriod = windll.winmm.timeBeginPeriod #new
timeBeginPeriod(1) #new

start = timer()
for i in range(1000):
    print (i)
    time.sleep(0.001)

end = timer()
print ("Total time: ", end - start)

警告:我读到这个高定时器分辨率将如何影响整体性能以及电池。我还没有看到任何发生的事情,Windows任务管理上的活动上的CPU使用率似乎也没有。但如果您的应用程序碰巧导致一些奇怪的行为,请记住这一点。