如何“多处理” 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是print
ing; I/O 很慢。
嗯,我的主脚本实际上是保存到数据库中,因为它正在计算不同的组合,因此也会减慢它的速度。
@Dougal:同意,I/O 很慢。他的问题将itertools.product
确定为瓶颈。如果他正在使用 I/O 进行计时,这应该会提示他。
@Noah R:根据您的评论,我会说您误诊了真正的瓶颈。不管你把它分成多少个进程,I/O 都可能是你的瓶颈。如果将 I/O 分配给多个进程,每个进程都连接到数据库,可能会更慢。
好吧,既然他说它使用巨大的multiprocessing.Pool
快速完成,显然并行性正在帮助他...但是是的,itertools.product
显然也不是真正的瓶颈。以上是关于如何“多处理” itertools 产品模块?的主要内容,如果未能解决你的问题,请参考以下文章
ImportError: cannot import name accumulate:如何在Python2中实现itertools的accumulate()?