python - 如何将多处理用于函数而不是循环?
问题描述
我写了一个包含大约 400 行的函数。该函数在数据帧上执行某种数据科学。当我运行该功能时,大约需要 10 秒。我需要在每次迭代中使用不同的参数运行这个函数 100 次。因此在循环中我调用该函数 100 次,并且每次迭代我输入 4 个不同的参数。总共花了大约15分钟。因此我想使用CPU Parallelization
. 如何在 python 中使用多处理来提供并行化并改善运行时?
代码示例:
result = []
for i range(100):
result.append(searching_algorithm(a[i], b[i], c[i], d[i]))
解决方案
您没有说 , 和 是什么a
类型b
的c
列表d
。这些列表中的元素必须能够使用pickle
模块进行序列化,因为它们需要传递给将由在不同地址空间中运行的进程执行的函数。为了论证,我们假设它们是至少长度为 100 的整数列表。
您也没有说明您在什么平台下运行(Windows?MacOS?Linux?)。当你用你标记一个问题时,multiprocessing
你应该也用平台标记这个问题。您如何组织代码在一定程度上取决于平台。在下面的代码中,我为那些spawn
用于创建新进程的平台(即 Windows)选择了最有效的安排。但这在 MacOS 和 Linux 上也很有效,它们默认用于fork
创建新进程。您可以研究与创建新流程相关的内容spawn
和fork
含义。最终要提高内存和 CPU 效率,您只希望作为if __name__ == '__main__':
块之外的全局变量,这些变量必须是全球的。这就是为什么我要声明一个函数的本地列表。
然后使用concurrent.futures
我们拥有的模块:
from concurrent.futures import ProcessPoolExecutor
def searching_algorithm(a, b, c, d):
...
return a * b * c * d
def main():
# We assume a, b, c and d each have 100 or more elements:
a = list(range(1, 101))
b = list(range(2, 102))
c = list(range(3, 103))
d = list(range(4, 104))
# Use all CPU cores:
with ProcessPoolExecutor() as executor:
result = list(executor.map(searching_algorithm, a[0:100], b[0:100], c[0:100], d[0:100]))
print(result[0], result[-1])
# Required for Windows:
if __name__ == '__main__':
main()
印刷:
24 106110600
要改用该multiprocessing
模块:
from multiprocessing import Pool
def searching_algorithm(a, b, c, d):
...
return a * b * c * d
def main():
# We assume a, b, c and d each have 100 or more elements:
a = list(range(1, 101))
b = list(range(2, 102))
c = list(range(3, 103))
d = list(range(4, 104))
# Use all CPU cores:
with Pool() as pool:
result = pool.starmap(searching_algorithm, zip(a[0:100], b[0:100], c[0:100], d[0:100]))
print(result[0], result[-1])
# Required for Windows:
if __name__ == '__main__':
main()
在这两个编码示例中,如果列表、a
和正好包含 100 个元素,则无需对它们进行切片,例如; 只需传递列表本身,例如:b
c
d
a[0:100]
result = list(executor.map(searching_algorithm, a, b, c, d))
推荐阅读
- mapbox - 有什么方法可以为 mapbox 中同一图层上的每个功能在悬停时提供不同的光标样式?
- angular - Angular 9 异步管道和搜索过滤器
- mysql - 迁移到 MySQL 8 后,Hibernate Criteria 查询不适用于日期时间列
- javascript - 在我设置某些状态后尝试将数据从子组件传递到安装上的父组件时出现恒定的无限循环
- methods - 哈希表是否支持与二叉搜索树相同的方法?
- spring-boot - 如何在所有客户端的春季会话空闲时间后重定向到登录页面
- sql - 选择姓名和姓氏作为客户
- javafx - JavaFX 应用程序源在加载时移动的问题
- python - Pythons Pandas - 有条件地循环数据框中的列并与参考数据集进行比较
- jquery - 确定哪个 div 滚动到顶部