[英]Why is time.sleep() accuracy influenced by Chrome?
我注意到一些奇怪的行為,這些行為可能特定於也可能不是特定於我的系統。 (運行 Windows 8 的聯想 t430)
使用這個腳本:
import time
now = time.time()
while True:
then = now
now = time.time()
dif = now - then
print(dif)
time.sleep(0.01)
在瀏覽器打開的情況下,我得到以下輸出(我認為是名義上的)。
但是,如果沒有打開瀏覽器,我會觀察到嚴重的每個循環延遲。
顯然,這是違反直覺的,因為我認為當並發進程較少時,任何人都希望獲得更好的性能。
對這些結果的任何見解或簡單復制將不勝感激。
編輯:有趣的是,我觀察到與此代碼類似的延遲:
import time
now = time.time()
def newSleep(mark,duration):
count = 0
while time.time()-mark < duration:
count+=1
print(count)
while True:
then = now
now = time.time()
dif = now - then
print(dif)
#time.sleep(0.01)
newSleep(now,0.01)
雖然它確實提供了額外的洞察力 - 那是一些潛在循環的實例是由於缺乏處理器可用性(通過打印 0 的計數來表示) - 我仍然注意到 15ms 的行為,其中打印的計數將高達 70k.. . 和 10 毫秒的行為,計數約為 40k。
我額外啟動了 Windows 7 來復制你的發現,我可以確認。
它是Windows 的東西,使用的計時器類型和默認分辨率為 15.6 毫秒(最小 0.5 毫秒)。 應用程序可以更改當前分辨率(WinAPI 函數: timeBeginPeriod ),而 Chrome 會這樣做。
此功能會影響全局 Windows 設置。 Windows 使用任何進程請求的最低值(即最高分辨率)。 設置更高的分辨率可以提高等待函數中超時間隔的准確性。 但是,它也會降低整體系統性能,因為線程調度程序更頻繁地切換任務。 高分辨率還可以防止 CPU 電源管理系統進入省電模式。 設置更高的分辨率不會提高高分辨率性能計數器的准確性。
福布斯2014 年的一篇文章介紹了 Chrome 中的一個錯誤,無論當前負載需要什么,該錯誤都會將分辨率永久設置為 1 毫秒——這是一個問題,因為它是一個系統范圍的影響,對能源消耗有影響。 從那篇文章:
在像 Windows 這樣的操作系統中,事件通常被設置為每隔一段時間運行一次。 為了省電,處理器在沒有任何需要注意的時候休眠,並在預定義的時間間隔喚醒。 這個間隔是 Chrome 在 Windows 中調整的,因此將其減少到 1.000 毫秒意味着系統喚醒的頻率遠高於 15.625 毫秒。 事實上,在 1.000 毫秒時,處理器每秒喚醒 1000 次。 默認值 15.625 毫秒意味着處理器每秒僅喚醒 64 次以檢查需要注意的事件。
微軟自己表示,1.000 毫秒的滴答率可能會使功耗增加“多達 25%”。
您可以使用time.get_clock_info()從 Python 獲取默認分辨率。
namespace = time.get_clock_info('time')
namespace.adjustable
# True
namespace.implementation
# 'GetSystemTimeAsFileTime()'
namespace.monotonic
# False
namespace.resolution
# 0.015600099999999999
您可以使用ClockRes小程序從cmd
獲取實際分辨率。
我在 windows 和 ubuntu 服務器(virtualbox)(沒有瀏覽器)中嘗試了相同的方法,但結果是相同的,我得到的平均值是
在 Ubuntu 服務器中
0.010122537612915039
0.010426998138427734
0.010067939758300781
0.010767221450805664
0.010728120803833008
0.010106086730957031
0.01068258285522461
0.010105609893798828
0.01118612289428711
0.010136842727661133
0.010585784912109375
0.010425567626953125
0.01014852523803711
0.010422945022583008
0.01010894775390625
在 Windows 中
0.010767221450805664
0.010751485824584961
0.010716915130615234
0.010229110717773438
0.01016545295715332
0.010195255279541016
0.010723352432250977
0.010744094848632812
0.010716438293457031
0.010564565658569336
0.010889291763305664
0.010728597640991211
0.010579824447631836
0.010889530181884766
0.010567903518676758
0.010717153549194336
0.010735273361206055
所以,在我看來,打開的瀏覽器和 python 的性能之間沒有相關性
對這些結果的任何見解或簡單復制將不勝感激。
干得好:
使用您的代碼和最新版本的 Chrome,我可以用幾乎相同的結果確認這種行為。
我測量了平均花費的時間-
瀏覽器運行:0.01055538261329734
瀏覽器未運行:0.01563055389053695
我有大約 30 個打開的選項卡,但它們都空閑。 目前,我想不出任何原因會發生這種情況。
期待進一步的見解。
雖然我無法在我的機器上重現這種行為,但我懷疑它可能是由動態處理器時鍾(以及內存和系統總線時鍾)引起的,例如,當您沒有打開瀏覽器時,處理器以 1/ 2 最大時鍾,但是一旦您啟動瀏覽器,它就會達到最大時鍾。 您可以通過在高級電源選項中使用“最大\\最小處理器狀態\\頻率”來驗證這一點,或者通過運行另一個產生許多進程的應用程序(這就是 Chrome 所做的)而不是瀏覽器來驗證這一點,看看這是否會改變延遲。
我寫了一個類似的代碼並得到了類似的輸出,
for i in range(10):
then = time.time()
time.sleep(0.01)
now = time.time()
# print('+---------------------------+')
print(now - then)
# print(f"rounded: {round(now - then, 2)}")
# print('+---------------------------+')
我首先懷疑是什么導致了這種情況,是浮點數學檢查這個的用法。
但后來我得到了這個輸出
輸出
0.01080012321472168
0.01015472412109375
0.010109186172485352
0.022491931915283203 # THIS ONE IS REALLY WEIRD
0.01163029670715332
0.010137796401977539
0.010179996490478516
0.01008749008178711
0.010132551193237305
0.010088443756103516
即使您假設在計算差異時存在誤差,也不應該有那么多
+---------------------------+
0.01080012321472168
rounded: 0.01
+---------------------------+
+---------------------------+
0.01015472412109375
rounded: 0.01
+---------------------------+
+---------------------------+
0.010109186172485352
rounded: 0.01
+---------------------------+
+---------------------------+
0.022491931915283203
rounded: 0.02
+---------------------------+
+---------------------------+
0.01163029670715332
rounded: 0.01
+---------------------------+
+---------------------------+
0.010137796401977539
rounded: 0.01
+---------------------------+
+---------------------------+
0.010179996490478516
rounded: 0.01
+---------------------------+
+---------------------------+
0.01008749008178711
rounded: 0.01
+---------------------------+
+---------------------------+
0.010132551193237305
rounded: 0.01
+---------------------------+
+---------------------------+
0.010088443756103516
rounded: 0.01
+---------------------------+
但是看了python官方的time.sleep
方法文檔后,這些結果是有道理的check here ,我引用了文檔
由於系統中其他活動的調度,暫停時間可能比任意數量的請求長
所以作為對這里問題的有根據的猜測,
它是由多種因素造成的
我希望這有幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.