[英]How to Speed up Python code by multiprocessing
我想通過使用多處理來加速我的 Python 代碼。
我讀到ProcessPoolExecutor
對我的目的來說是最好的,但我怎樣才能做到這一點。 我有一個這樣的程序:
for resource_file in tmp_resource_folder.iterdir():
with resource_file.open() as f:
ns_resources = yaml.safe_load(f)
resources = ns_resources.get('items')
for resource in resources:
-----------------
Slow opperations
-----------------
如何將第一個循環的每次迭代都運行到子進程中並實現代碼的加速。 同樣在迭代之后,我想等待所有子操作完成后再繼續。
提前致謝!
最簡單的方法是使用multiprocessing.Pool
和imap
方法:
import multiprocessing
def worker(resource_file):
with resource_file.open() as f:
ns_resources = yaml.safe_load(f)
resources = ns_resources.get('items')
for resource in resources:
-----------------
Slow opperations
-----------------
def main():
pool = multiprocessing.Pool()
pool.imap(worker, tmp_resource_folder.iterdir())
# wait for tasks to finish:
pool.close()
pool.join()
# required for Windows:
if __name__ == '__main__':
main()
除了使用imap
,您也可以只使用方法map
,如下所示:
def main():
pool = multiprocessing.Pool()
pool.map(worker, tmp_resource_folder.iterdir())
以下是imap
和map
區別的技術性描述,您可以忽略。 但我建議您閱讀multiprocessing
模塊中的各種Pool
方法。
潛在的缺點是map
方法將有效地處理調用,就好像您編寫了以下代碼一樣:
pool.map(worker, list(tmp_resource_folder.iterdir()))
也就是說,它將可迭代參數轉換為列表,以便它可以采用長度。 如果文件數量非常大,這可能會導致使用大量 memory。 但它這樣做是為了計算一個有效的塊大小值,該值用於設置它一次排隊的任務數到池中的每個進程,以減少它必須排隊的memory傳輸的數量任務。 這可以提高性能。 imap
默認使用 1 的chunksize值,這對於非常大的迭代不是特別有效,但您可以為imap
指定第三個參數,這是要使用的chunksize值。 但是要指定一個智能值,您確實需要知道最終要提交的文件總數。
map將計算的map
大小本質上是可迭代大小除以 4 * 池大小:
def compute_chunksize(pool_size, iterable_size):
chunk_size, remainder = divmod(iterable_size, 4 * pool_size)
if remainder:
chunk_size += 1
return chunk_size
因此,例如,如果iterdir()
最終會返回 30 個文件並且池大小為 8(因為您有 8 個內核), compute_chunksize
將返回 1。如果您有 33 到 64 個文件,則compute_chunksize
將返回 2。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.