[英]Create a set with multiprocessing
我有很多物品,还有一些辅助数据。 对于列表中的每个项目和数据中的元素,我计算一些东西,然后将所有东西添加到输出集中(可能有很多重复项)。 在代码中:
def process_list(myList, data):
ret = set()
for item in myList:
for foo in data:
thing = compute(item, foo)
ret.add(thing)
return ret
if __name__ == "__main__":
data = create_data()
myList = create_list()
what_I_Want = process_list(myList, data)
由于myList很大,compute(item,foo)的成本很高,因此我需要使用多处理。 现在这就是我所拥有的:
from multiprocessing import Pool
initialize_worker(bar):
global data
data = bar
def process_item(item):
ret = set()
for foo in data:
thing = compute(item, foo)
ret.add(thing)
return ret
if __name__ == "__main__":
data = create_data()
myList = create_list()
p = Pool(nb_proc, initializer = initialize_worker, initiargs = (data))
ret = p.map(process_item, myList)
what_I_Want = set().union(*ret)
我对此不满意的是,ret可能很大。 我正在考虑3个选项:
1)将myList切成块,然后将其传递给工作人员,工作人员将在每个块上使用process_list(因此,在该步骤中将删除一些重复项),然后将所有获得的集合合并以删除最后的重复项。
问题:是否有一种优雅的方法? 我们是否可以指定给Pool.map,它应该将数据块传递给工作程序,而不是数据块中的每个项目? 我知道我可以自己砍名单,但这真丑。
2)在所有进程之间有一个共享集。
问题 :为什么multiprocessing.manager不具有set()功能? (我知道它具有dict(),但仍然..。)如果我使用manager.dict(),进程和管理器之间的通信会不会大大降低速度?
3)有一个共享的multiprocessing.Queue()。 每个工作人员将其计算的内容放入队列。 另一个工作人员进行联合,直到找到一些stopItem(我们将其放在p.map之后的队列中)
问题:这是一个愚蠢的主意吗? 进程和multiprocessing.Queue之间的通信是否比使用manager.dict()的通信更快? 另外,我如何取回由工人进行联合计算的集合?
一件小事: initiargs
需要一个元组。
如果要避免在将所有结果归为一set
之前避免创建所有结果,则可以使用具有一些块大小的Pool.imap_unordered()
。 当每个工人可用时,这将产生块大小结果。
如果要更改process_item
以直接接受块,则必须手动执行。 toolz.partition_all
可用于对初始数据集进行分区。
最后,托管数据结构必然具有更高的同步开销。 我会尽量避免它们。
使用imap_unordered
看看是否足够好; 如果没有,则进行分区; 如果您总共不能重复几个重复,请使用托管字典。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.