我正在尝试获得所有可能的组合与替换,并对它们中的每一个进行一些计算。我正在使用下面的代码:
from itertools import combination_with_replacement
for seq in combination_with_replacement('ABCDE', 500):
# some calculation
如何使用多处理并行化此计算?
您可以使用标准库concurrent.futures
。
from concurrent.futures import ProcessPoolExecutor
from itertools import combinations_with_replacement
def processing(combination):
print(combination)
# Compute interesting stuff
if __name__ == '__main__':
executor = ProcessPoolExecutor(max_workers=8)
result = executor.map(processing, combinations_with_replacement('ABCDE', 25))
for r in result:
# do stuff ...
多一点解释:
- 此代码使用
processes
创建执行程序。另一种可能性是使用threads
但完整的 python 线程只在一个内核上运行,因此它可能不是您感兴趣的解决方案,因为您需要运行大量计算。 - 映射对象返回异步对象。因此,行
executor.map..
是非阻塞的,您可以在for
循环中收集结果之前执行其他计算。 - 在
if __name__ == '__main__':
块之外声明processing
函数并在此块中声明和使用执行器非常重要。这可以防止无限执行器生成,并允许pickle
工作器函数以将其传递给子进程。如果没有此块,代码可能会失败。
我推荐它而不是multiprocessing.Pool
因为它在使用迭代器时有一种更聪明的方式来调度工作。
请注意,可能无法计算500
与 5 个元素ABCDE
的组合。它需要计算5**500 > 1e350
元素。通过并行化,您只会将计算线性减少max_workers
倍数,因此在这种情况下,8
并且每个进程都需要使用~ 1e349
个元素运行,如果每次计算在 1 微秒内完成,这应该需要大约~ 1e335
年的时间。