我在python中有一个用于列表功率集的生成器,我想使用multiprocessing模块对这些集合的元素进行一些计算。我的代码如下:
def powerset(seq):
'''Returns all the subsets of the list. This is a generator.'''
if len(seq) == 0:
yield seq
if len(seq) == 1:
yield seq
yield []
elif len(seq) > 1:
for item in powerset(seq[1:]):
yield [seq[0]]+item
yield item
def job(l):
# do some calculation with the list l
return do_some_hard_work(l)
def calculate():
pool_size = multiprocessing.cpu_count() * 2
pool = multiprocessing.Pool(processes=pool_size, maxtasksperchild=2)
pool_outputs = pool.map(job, powerset(list(range(1,10)))
pool.close()
pool.join()
return sum(pool_outputs)
问题在于电源设置功能是一个发电机,将无法正常工作。但是我不能更换发电机,因为在计算需要大量时间和内存之前生成孔功率集。有谁知道我如何解决这个问题?
最佳答案
如果问题是您希望避免将整个powerset放在列表中,则可以使用pool.imap
,这将一次消耗迭代器chunksize
元素,并将其发送给工作进程,而不是发送给工作进程将整个内容转换为列表并将其分块。
pool_size = multiprocessing.cpu_count() * 2
pool = multiprocessing.Pool(processes=pool_size, maxtasksperchild=2)
pool_outputs = pool.imap(job, powerset(list(range(1,10))), chunksize=<some chunksize>)
pool.close()
pool.join()
如果您的幂集非常大,则需要指定默认值以外的
chunksize
:1:chunksize参数与map()使用的参数相同
方法。对于很长的可迭代对象,使用较大的块大小值可以
使作业完成比使用默认值1快得多。
map
函数使用以下算法,为您提供一个不错的选择:chunksize, extra = divmod(len(iterable), len(pool_size) * 4)
if extra:
chunksize += 1