Python 多功能的多处理
假设我有100k个JSON,其中包含大量数据,Python 多功能的多处理,python,python-3.x,multiprocessing,Python,Python 3.x,Multiprocessing,假设我有100k个JSON,其中包含大量数据,data\u JSON是包含这些文件名的列表 另外,假设我有3个函数: 1) 上传数据() 2) data\u preprocess\u 1() 3) data\u preprocess\u 2() 这些函数可以分别为每个json调用,因此它们都是并行的 总体而言,多处理我的代码的最佳方式是什么 一个选项(非常粗略地描述)如下: import os from multiprocessing import Pool def upload_data(
data\u JSON
是包含这些文件名的列表
另外,假设我有3个函数:
1) 上传数据()
2) data\u preprocess\u 1()
3) data\u preprocess\u 2()
这些函数可以分别为每个json调用,因此它们都是并行的
总体而言,多处理我的代码的最佳方式是什么
一个选项(非常粗略地描述)如下:
import os
from multiprocessing import Pool
def upload_data():
...
def data_preprocess_1():
...
def data_preprocess_2():
...
if __name__ == '__main__':
pool = Pool(processes=os.cpu_count())
temp_1 = pool.map(upload_data, json_files)
pool = Pool(processes=os.cpu_count())
temp_2 = pool.map(data_preprocess_1, temp_1)
pool = Pool(processes=os.cpu_count())
final = pool.map(data_preprocess_2, temp_2)
import os
from multiprocessing import Pool
def upload_data():
...
def data_preprocess_1():
...
def data_preprocess_2():
...
def data_all():
upload_data()
data_preprocess_1()
data_preprocess_2()
...
if __name__ == '__main__':
pool = Pool(processes=os.cpu_count())
final = pool.map(data_all, data_jsons)
但据我所知,通过这种方式,我可以分别并行每个函数,而我可以同时并行所有函数,以避免用所有数据加载temp_1
和temp_2
(这将占用大量内存)
我认为避免这种情况的选择(非常粗略地描述)如下:
import os
from multiprocessing import Pool
def upload_data():
...
def data_preprocess_1():
...
def data_preprocess_2():
...
if __name__ == '__main__':
pool = Pool(processes=os.cpu_count())
temp_1 = pool.map(upload_data, json_files)
pool = Pool(processes=os.cpu_count())
temp_2 = pool.map(data_preprocess_1, temp_1)
pool = Pool(processes=os.cpu_count())
final = pool.map(data_preprocess_2, temp_2)
import os
from multiprocessing import Pool
def upload_data():
...
def data_preprocess_1():
...
def data_preprocess_2():
...
def data_all():
upload_data()
data_preprocess_1()
data_preprocess_2()
...
if __name__ == '__main__':
pool = Pool(processes=os.cpu_count())
final = pool.map(data_all, data_jsons)
还有什么我没有的选择吗
我所描述的选项是否有问题
我不想将这3个函数合并为一个函数,只是想说明一下原因,因为它们中的每一个函数都执行不同的子任务。对于任何优化问题,请从基准开始 也就是说,您几乎肯定希望有一种类似
data\u all()
的机制,而不是使用中间存储。对于许多可能需要应用多处理的情况,主要的成本是将对象从一个进程的内存移动到另一个进程的内存中,唯一的抵消方法是为传输的每一位数据做更多的工作
对于你的另一个问题,关于你是否还缺少其他选择,有很多。您可以在流程的任何步骤中进行不同类型的批处理、流式处理或其他类型的操作和转换,这些操作和转换可能会改变管道的性能特征。使用其他类型的体系结构可以降低峰值内存使用率,但这是否重要(或是否可行)取决于您的确切数据。谢谢您的回答(upvote)。关于你的第二段,你似乎同意我的第二个选择。关于你的第3段,正如你所说,有无限的选择不同的批处理,操纵等。我的问题主要是,如果有任何明显的一个是“游戏规则改变者”?例如,在我的帖子中,与第一个选项相比,第二个选项是一个游戏规则改变者,一般来说,前者比后者好一个顺序。同样地,我想知道是否有其他的选择比我的第二个选择“一个订单”更好(但似乎没有?),不一定。没有任何改变游戏规则的人能让游戏本身变得更快。但是,如果您的结果不容易放入RAM或具有其他不需要的属性,那么盲目地抛出问题的
Pool.map
将不会很好地工作(它返回一个列表,因此每个结果都会立即缓存在RAM中)。在这种情况下,一种方法是成批迭代数据,将Pool.map
应用到足够小的批中,并从这些批中生成结果(或者推送到发布/订阅系统,存储在数据库或文件中,无论您对数据做什么)。如果我们纯粹将其视为对数据进行优化所需的总时间,这些数据大到需要多个处理,复杂到您的data\u all()
需要的时间比将数据从一个进程复制到另一个进程所需的时间长,并且小到可以轻松放入RAM,那么您实际上只有您第一次提到的两个选项需要担心,而在这两个选项之间,几乎可以肯定的是data\u all()
方法更好(尽管仍然可能不会比根本不进行多处理更快)。若你们有更多的约束,你们会得到更复杂的解决方案,比如批处理。是的,将批处理添加到池中一定会使它变得更好。因此,如果我理解的很好,你也认为我的帖子中的第二个选项与第一个相比是一个游戏规则改变者,与第二个相比,没有另一个明显的游戏规则改变者(除非我们应用批处理,这可以成为一个新的游戏规则改变者)。