1

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

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 新手。

4

1 回答 1

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()
于 2012-12-24T02:18:11.677 回答