使用多处理迭代一个powerset

时间:2014-08-29 11:48:52

标签: python python-3.x multiprocessing

我在python中有一个列表的powerset生成器,我想使用多处理模块对这些集合的元素进行一些计算。我的代码如下:

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-function是一个生成器,不起作用。但是我无法替换发生器,因为在计算需要很多时间和内存之前生成孔poweret。有谁知道如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

如果问题是你想避免将整个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()

如果您的powerset非常大,您需要指定除默认值之外的chunksize,即1:

  

chunksize参数与map()使用的参数相同   方法。对于使用较大值的chunksize可以进行很长时间的迭代   使用默认值1来快速完成工作。

map函数使用以下算法,让您了解好大小:

chunksize, extra = divmod(len(iterable), len(pool_size) * 4)
if extra:
    chunksize += 1