GzipFile中的缓冲处理

3

想象一下以下简单的脚本:

def reader():
    for line in open('logfile.log'):
        # do some stuff here like splitting the line or filtering etc.
        yield some_new_line

def writer(stream):
    with gzip.GzipFile('some_output_file.gz', 'w') as fh:
        for _s in stream:
            fh.write(_s+'\n')

stream = reader()
writer(stream)

很简单-使用生成器读取行,并将一些结果写入gzip文件。但如何提高速度?硬盘似乎是瓶颈。我看到可以使用缓冲读取 - 使用open(file,mode,buffer)语法。但我不太确定它是否适用于我的情况(使用生成器)。此外,我没有找到gzip.GzipFile调用的任何缓冲参数。从代码中看,它基于某些缓冲类,但我没有看到任何进一步的文档。我有一个(疯狂的?)想法,创建一个显式缓存,并用它替换打开方法 - 这样它就会按8MB等更大块读取文件,然后按行拆分。至于写入,我想创建要写入的行列表,收集它们(例如5000行),然后转储到文件中。我试图重复发明轮子吗?我对脚本当前的性能不满意,因此我尽可能地尝试加速它。更新:我大约有4-5个不同的并行工作人员在运行。他们都执行读取和写入操作。因此,我想要实现一些缓冲以便定期以大块方式转储数据。谢谢!

这不是一个疯狂的想法。但是Python在迭代文件时已经执行了缓存操作,因此您可能只需要优化写入部分。 - Leonardo.Z
1个回答

0

我可以提出更紧凑的代码:

def reader():
    for line in open('logfile.log'):
        # do some stuff here like splitting the line or filtering etc.
        yield some_new_line

def writer(stream):
    with gzip.GzipFile('some_output_file.gz', 'w') as fh:
        fh.writelines(stream)

writer(reader())

然而,实际上并没有加速。Python将管理流,但如果您不能为完整文件写入腾出内存,则加速效果不会很大。

尽管gzip压缩是最慢的步骤。以下函数将仅为您提供约3%的加速效果(不考虑生成器部分)。

def writer():
   f = open('logfile.log').read()
   gzip.GzipFile('some_output_file.gz', 'w').write(f)
writer()

所以,如果你需要gzip,那么你就无能为力了。


你的意思是gzip算法本身很慢,需要太多的CPU时间吗?我有大约4-5个不同的并行进程,它们执行读写操作,硬盘花费了很多时间跳转到另一个扇区。这就是为什么我想缓冲数据,并定期将其转储到硬盘上的原因。 - Spaceman
@Spaceman:gzip.write 占用了你代码执行时间的90%以上。如果将你的写入器替换为普通的保存模式:“with open('some_output_file', 'w') as fh: fh.writelines(stream)”,那么对于小型输入文件,你的代码可在毫秒内执行。如果使用gzip编写器,则对于相同的输入文件,需要几秒钟才能完成操作。我的结论是gzip至少会使代码变慢100倍。 - Ivaylo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接