2016-11-14 65 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

相關問題