2016-11-14 245 views
1

我循环1000次,延时1ms,计算总时间。总时间是15.6秒而非1,这非常有趣。当我打开谷歌浏览器并浏览了一些网站时,它总共运行了1秒。此外,它也适用于Macbook。 我想知道我需要做什么样的解决方案来解决这个问题?请尝试运行它,而不使用Chrome打开Chrome浏览器,以查看区别。当我的系统上打开Quora或Reddit或Stackoverflow时,它正常运行。为什么time.sleep()在Windows中如此之慢?

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/

+0

你是如何在Chrome中运行python的?这很混乱。 –

+2

你的错误是假设'睡眠(0.001)'会睡一毫秒,而不是*至少* 1毫秒。您可能想阅读http://stackoverflow.com/questions/9518106 –

+0

对Eli:我没有在Python上运行它。我刚刚打开Chrome浏览器并浏览了一些网站以加快时间延迟。对困惑感到抱歉。 –

回答

2

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

因此,为了解决这个问题,我需要调用一个名为timeBeginPeriod(period)的Windows函数来更改分辨率计时器。幸运的是,python使我可以通过提供​​库来修复它。最后的代码下面提供:

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使用率似乎也无法压倒一切。但请记住,如果您的应用程序碰巧导致一些奇怪的行为。

+1

具有错误检查和上下文管理的[更清晰的实现](http://stackoverflow.com/a/38488544/205580)。当然,对于任何关键的事情来说这都是不可靠的,因为它受到系统上运行的其他软件的支配。如果你需要关键的时机,你最好用'time.perf_counter()'循环繁忙,而不是依靠系统调度器。 – eryksun

+0

@eryksun:嗨eryksun,谢谢你的建议。你的方法能保证每个周期的准确时间延迟吗?矿井仍然是0.1或0.2毫秒,这有点不好,因为我的应用是以恒定速率绘制点。从速度上稍微偏离会使情节看起来很糟糕。 –

+0

在Windows上,'timer.perf_counter'调用['QueryPerformanceCounter'](https://msdn.microsoft.com/en-us/library/ms644904),它是一个至少1微秒分辨率的单调时钟。检查'time.get_clock_info('perf_counter')'。 – eryksun

相关问题