如何“多处理” itertools 产品模块?

Posted

技术标签:

【中文标题】如何“多处理” itertools 产品模块?【英文标题】:How do I "multi-process" the itertools product module? 【发布时间】:2012-04-21 19:12:48 【问题描述】:

所以我尝试计算以下字符串的数百万个不同组合,但我每秒只计算大约 1,750 个组合,这甚至不接近我需要的速度。那么我将如何重塑这一点,使同一事物的多个过程计算不同的部分,而不计算已经计算的部分并保持快速?下面的代码部分是我一直在使用的。任何示例将不胜感激!

from itertools import product
for chars in product("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12234567890!@#$%^&*?,()-=+[]/;", repeat = 4):
   print chars

【问题讨论】:

【参考方案1】:

将产品分解成多个部分的一种方法是将产品的第一个组件分解,这样每个独立的工作都具有以一组特定首字母开头的所有元素。例如:

import string
import multiprocessing as mp
import itertools

alphabet = string.ascii_letters+string.digits+"!@#$%^&*?,()-=+[]/;"
num_parts = 4
part_size = len(alphabet) // num_parts

def do_job(first_bits):
    for x in itertools.product(first_bits, alphabet, alphabet, alphabet):
        print(x)

if __name__ == "__main__":
    pool = mp.Pool()
    results = []
    for i in xrange(num_parts):
        if i == num_parts - 1:
            first_bit = alphabet[part_size * i :]
        else:
            first_bit = alphabet[part_size * i : part_size * (i+1)]
        results.append(pool.apply_async(do_job(first_bit)))

    pool.close()
    pool.join()

(显然,如果do_job 实际返回了某些内容,您只会使用results)。

【讨论】:

好的,我这样做了,它在大约 10 秒内完成了它自己。坏事是我所有的电脑资源都被占用了,差点心脏病发作。我如何限制线程数量,因为我启动了任务管理器并且一次运行了大约 80 个 python 进程。 :) 这就是我在multiprocessing.Pool 中遗漏的... 的用途。尝试例如Pool(processes=4)。请参阅the multiprocessing docs 了解更多信息。 好吧,我把它切换到 4 个进程,它变得更糟,一次打开了几百个,然后我的电脑崩溃了。 如果你说 4 个进程,那么 multiprocessing 应该只启动 4 个进程——你是否在你的代码中做其他事情来启动 Python 进程? @NoahR 我敢打赌你在 Windows 上,对吧? multiprocessing 实际上是在 Windows 上导入模块,而像我这样的 Unix 操作系统不会发生这种情况,因此池中的每个元素都在生成自己的池。使用__main__ 检查新版本。【参考方案2】:

您确定每秒只能获得 1750 个组合吗?我得到了大约 1000 万。

def test(n):
    start = time.time()
    count = 0
    for chars in product("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ12234567890!@#$%^&*?,()-=+[]/;", repeat = 4):

        count += 1
        if count == n: break
    return time.time() - start    

>>> test(10000)
0.03300023078918457
>>> test(1000000)
0.15799999237060547
>>> test(10000000)
1.0469999313354492

我不认为我的电脑比你的电脑快那么多

注意:我发布这个作为答案是因为我想展示代码。这真的更像是一个评论。所以,请不要赞成或反对。

【讨论】:

不同之处可能是当你只是循环时OP是printing; I/O 很慢。 嗯,我的主脚本实际上是保存到数据库中,因为它正在计算不同的组合,因此也会减慢它的速度。 @Dougal:同意,I/O 很慢。他的问题将itertools.product 确定为瓶颈。如果他正在使用 I/O 进行计时,这应该会提示他。 @Noah R:根据您的评论,我会说您误诊了真正的瓶颈。不管你把它分成多少个进程,I/O 都可能是你的瓶颈。如果将 I/O 分配给多个进程,每个进程都连接到数据库,可能会更慢。 好吧,既然他说它使用巨大的multiprocessing.Pool 快​​速完成,显然并行性正在帮助他...但是是的,itertools.product 显然也不是真正的瓶颈。

以上是关于如何“多处理” itertools 产品模块?的主要内容,如果未能解决你的问题,请参考以下文章

如何嵌套 itertools 产品?

python 多处理示例 itertools 多个列表

ImportError: cannot import name accumulate:如何在Python2中实现itertools的accumulate()?

多处理计算中map()模块和imap()之间的差异

一日一技:如何让 itertools.tee 线程安全

具有多处理功能的 Python itertools - 巨大的列表与使用迭代器的 CPU 使用效率低下