python itertools产品慢是输出文件的写入速度的瓶颈

时间:2012-12-24 00:46:38

标签: python product itertools

我有一个简单的python函数执行itertools产品功能。如下所示。

def cart(n, seq):
    import itertools
    b = 8
    while b < n:
        n = n - 1
        for p in itertools.product(seq, repeat=n):
            file.write(''.join(p))
            file.write('\n')

该功能有效,但速度极慢。它甚至没有使用大量的资源。我想知道瓶颈是否是磁盘写入速度?目前该脚本的平均速度为每秒2.5 MB。我也试过这个固态驱动器并收到相同的速度,这让我相信写入速度不是瓶颈。有没有办法加快这个功能并使用更多的系统资源?或者是itertools只是慢?原谅我,我是python的新手。

1 个答案:

答案 0 :(得分:2)

您可以对代码进行分析,以了解瓶颈的位置。下面将创建一个名为“cart_stats.txt”的文件,其中包含分析信息。自己运行似乎表明大部分时间都花在调用file.write()上。

from cProfile import Profile
from pstats import Stats
prof = Profile()
prof.disable()

file = open('cart_output.txt', 'wt')

def cart(n, seq):
    import itertools
    b = 8
    while b < n:
        n = n - 1
        for p in itertools.product(seq, repeat=n):
            file.write(''.join(p))
            file.write('\n')

prof.enable()
cart(10, 'abc')
prof.disable()

prof.dump_stats('cart.stats')
with open('cart_stats.txt', 'wt') as output:
    stats = Stats('cart.stats', stream=output)
    stats.sort_stats('cumulative', 'time')
    stats.print_stats()

file.close()
print 'done'

FWIW,缓慢似乎是由于调用file.write()本身而导致的,因为它仍然存在,即使我open()输出流具有巨大的缓冲区或使其成为StringIO实例。通过优化和最小化对它的调用,我能够显着降低这一点,如下所示:

def cart(n, seq):
    import itertools
    b = 8
    write = file.write  # speed up lookup of method
    while b < n:
        n = n - 1
        for p in itertools.product(seq, repeat=n):
            write(''.join(p)+'\n')  # only call it once in loop

这证明拥有一个分析器可以是知道在哪里花费时间并获得最大收益的最佳方式。

<强>更新

这是一个版本,用于存储在进行单个file.write()调用之前在内存中生成的所有输出。它比使用StringIO.StringIO快得多,因为它不那么通用,但是仍然没有使用cStringIO.StringIO实例那么快。

file = open('cart_output.txt', 'wt')

def cart(n, seq):
    from itertools import product
    buflist = []
    append = buflist.append
    b = 8
    while b < n:
        n = n - 1
        for p in product(seq, repeat=n):
            append(''.join(p))
    file.write('\n'.join(buflist)+'\n')

file.close()