私はcProfileで継承したいくつかのレガシーコードをプロファイリングしました。すでにシンプルジョーンズのCの拡張機能を使っているような、私がすでに手がけてきた変更がたくさんありました。ファイルへの書き込みを高速化する
基本的に、このスクリプトはあるシステムからASCII固定幅ファイルにデータをエクスポートしています。各行はレコードであり、多くの値を持っています。各行は7158文字で、1トンのスペースが含まれています。総レコード数は150万レコードです。各行は一度に1つずつ生成され、しばらく時間がかかります(1秒あたり5〜10行)。
各行が生成されるたびに、できるだけ簡単にディスクに書き込まれます。プロファイリングは、約の合計時間の19-20%がfile.write()
で費やされていることを示しています。 1,500行のテストケースの場合、20秒です。私はその数を減らしたいと思います。
次の勝利は、ディスクへの書き込みに費やされる時間を減らすことになります。可能であれば、それを減らしたいと思います。私はメモリ内のレコードのキャッシュを保持することができますが、私は最後まで待つことはできず、一度にすべてをダンプします。
fd = open(data_file, 'w')
for c, (recordid, values) in enumerate(generatevalues()):
row = prep_row(recordid, values)
fd.write(row)
if c % 117 == 0:
if limit > 0 and c >= limit:
break
sys.stdout.write('\r%s @ %s' % (str(c + 1).rjust(7), datetime.now()))
sys.stdout.flush()
私の最初の考えは、レコードのキャッシュをリストに保存し、バッチで書き出すことです。それはより速いでしょうか?何かのように:
rows = []
for c, (recordid, values) in enumerate(generatevalues()):
rows.append(prep_row(recordid, values))
if c % 117 == 0:
fd.write('\n'.join(rows))
rows = []
私の2番目の考えは、別のスレッドを使用することですが、それは私の中で死ぬことができます。
アプリケーションのボトルネックは何ですか? –
私は明らかだと思った。一度にディスクの1行に20%の書き込み時間を費やしています。 – chmullig
さて、変更してプロファイルしますか?ファイルI/Oは通常バッファリングされているので、効果はほとんどないと思います。 – delnan