簡體   English   中英

Python 3.8 將 for 循環轉換為多處理/多線程

[英]Python 3.8 Convert for loop to multiprocessing/multithreading

我是多處理的新手,如果有人可以在這里指導/幫助我,我將不勝感激。 我有以下 for 循環,它從兩個函數中獲取一些數據。 代碼看起來像這樣

    for a in accounts:
        dl_users[a['Email']] = get_dl_users(a['Email'], adConn)
        group_users[a['Email']] = get_group_users(a['Id'], adConn)

    print(f"Users part of DL - {dl_users}")
    print(f"Users part of groups - {group_users}")
    adConn.unbind()

這可以正常工作並獲得所有結果,但最近我注意到獲取用戶列表(即 dl_users 和 group_users)需要花費大量時間。 大約需要 14-15 分鍾才能完成。 我正在尋找可以加快 function 的方法,並希望將這個 for 循環轉換為多處理。 get_group_usersget_dl_users調用 LDAP,所以我不能 100% 確定是否應該將其轉換為多處理或多線程。 任何建議都會有很大幫助

正如評論中提到的,多線程適用於 I/O 操作(讀取/寫入文件、發送 http 請求、與數據庫通信),而多處理適用於 CPU 密集型任務(例如轉換數據、進行計算。 ..)。 根據您的函數執行哪種操作,您需要其中一種。 如果他們混合使用,請在內部將它們分開並分析兩者中的哪一個真正需要優化,因為多處理和 -threading 都會引入可能不值得添加的開銷。

也就是說,在最近的 Python 版本(包括您的 3.8)中,應用多處理或多線程的方法非常簡單。

多處理

from multiprocessing import Pool


# Pick the amount of processes that works best for you
processes = 4

with Pool(processes) as pool:
    processed = pool.map(your_func, your_data)

其中your_func是 function 應用於your_data的每個元素,這是一個可迭代的。 如果需要為可調用對象提供一些其他參數,可以使用 lambda function:

processed = pool.map(lambda item: your_func(item, some_kwarg="some value"), your_data)

多線程

多線程的 API 非常相似:

from concurrent.futures import ThreadPoolExecutor


# Pick the amount of workers that works best for you.
# Most likely equal to the amount of threads of your machine.
workers = 4

with ThreadPoolExecutor(workers) as pool:
    processed = pool.map(your_func, your_data)

如果您想避免將your_data存儲在 memory 中,如果您需要項目的某些屬性而不是項目本身,則可以使用生成器:

processed = pool.map(your_func, (account["Email"] for account in accounts))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM