加快写入文件的速度

时间:2011-02-10 19:20:18

标签: python performance file-io

我已经描述了一些我用cProfile继承的遗留代码。我已经做了一些有帮助的改变(比如使用simplejson的C扩展!)。

这个脚本基本上是将数据从一个系统导出到ASCII固定宽度文件。每行都是一条记录,它有很多值。每行7158个字符,包含大量空格。总记录数为150万条记录。每行生成一行,并且需要一段时间(每秒5-10行)。

生成每一行时,尽可能简单地将其写入磁盘。分析表明约{strong> 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 = []

我的第二个想法是使用另一个线程,但这让我想死在里面。

3 个答案:

答案 0 :(得分:32)

实际上,问题不在于file.write()需要20%的时间。它有80%的时间不在file.write()

写入磁盘很慢。你真的无能为力。将内容写入磁盘只需要很长的时间。你无法做任何事情来加速它。

您想要的是I / O时间是程序的最大部分,因此您的速度受硬盘速度的限制而不是您的处理时间。理想情况是file.write()有100%的使用率!

答案 1 :(得分:20)

将写入分组为500个组确实显着加快了写入速度。对于此测试用例,写入行在I / O中单独占用21.051秒,而分批写入117则需要5.685秒来写入相同数量的行。 500个批次总共只用了0.266秒。

答案 2 :(得分:1)

您可以在python中执行mmap可能帮助。但是我怀疑你在分析时犯了一些错误,因为在20秒内7k * 1500大约是0.5 Mbytes / s。做一个你用相同长度编写随机行的测试,你会发现它比这快得多。