繁体   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