繁体   English   中英

通过多处理创建集合

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM