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')

機能は動作しますが、非常に遅いです。目立った量のリソースを使用していません。ボトルネックはディスクの書き込み速度だったのだろうか?現在、スクリプトの平均は1秒あたり2.5MBです。また、これをソリッドステートドライブで試し、同じ速度を受け取ったため、書き込み速度はボトルネックではないと思われました。この機能を高速化し、より多くのシステムリソースを使用する方法はありますか?または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()呼び出しを行う前に、生成されたすべての出力をメモリに保存するバージョンを次に示します。一般的ではないため、using よりも大幅に高速ですが、インスタンス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 に答える