我正在使用這個庫,Tomorrow,它依次使用標準庫中的ThreadPoolExecutor,以允許Async函數調用。爲什麼一個工作者的ThreadPoolExecutor仍然比正常執行更快?
調用@tomorrow.threads(1)
1名工人旋轉了的ThreadPoolExecutor裝飾。
問題
- 爲什麼更快地執行使用
1 thread worker
在打電話只是它是(例如正常)的功能? - 爲什麼使用
10 thread workers
代替1,甚至是None執行相同的代碼會更慢?
演示代碼
進口排除
def openSync(path: str):
for row in open(path):
for _ in row:
pass
@tomorrow.threads(1)
def openAsync1(path: str):
openSync(path)
@tomorrow.threads(10)
def openAsync10(path: str):
openSync(path)
def openAll(paths: list):
def do(func: callable)->float:
t = time.time()
[func(p) for p in paths]
t = time.time() - t
return t
print(do(openSync))
print(do(openAsync1))
print(do(openAsync10))
openAll(glob.glob("data/*"))
注:data
文件夾中包含18個文件,每個700線隨機文字。
輸出
0工人: 0.0120秒
1工人: 0.0009秒
10個工人: 0.0535秒
我有什麼測試
- 我已經跑了代碼比夫婦dusin時間多,不同的程序在後臺運行(昨天跑了一堆,今天一對夫婦)。數字改變,ofc,但順序始終相同。 (即,1是最快的,然後是0,然後是10)。
- 我也嘗試改變執行順序(例如移動do調用)以消除緩存作爲因素,但仍然是一樣的。
- 原來,以不同的順序按照該次序執行
10
,1
,None
結果(1是最快的,然後如圖10所示,然後0)相比每個其他排列。結果表明,不管do
調用是否最後執行,都比它先執行或中間執行時慢得多。
- 原來,以不同的順序按照該次序執行
結果(從@Dunes接收溶液後)
0工人: 0.0122秒
1工人: 0。0214秒
10個工人: 0.0296秒
對於任何接近準確的性能統計數據的事情,您的樣本量可能太小。在測試諸如文件操作等事情時,您還需要考慮緩存(在操作系統內)的影響。 –
@DarkFalcon我運行的代碼不僅僅是一段時間,不同的程序在後臺運行(昨天跑了一堆,今天跑了一對)。數字改變,ofc,但順序始終相同。 我也嘗試交換執行的順序,例如移動「做」電話。還是一樣。 – Olian04
您的測試顯示不正確。也就是說,在結束測試之前,異步變體不需要等待所有工作完成。也就是說,您只需計算設置所有工作線程需要多長時間,而不需要這些線程完成工作所需的時間。 – Dunes