有没有一种方法可以比我的脚本更快地读取GB大小的文本文件?

时间:2020-01-22 06:05:33

标签: python replace

我编写了一个python脚本,可以快速读取和替换Gb大小的文件夹中的多个文本文件。有没有一种方法可以比我的脚本更快速地执行此操作?脚本运行吗?

    import re
    import os

    drc = '/root/tmp'
    pattern = re.compile('"')
    oldstr = '"'
    newstr = ''

    for dirpath, dirname, filename in os.walk(drc):
        for fname in filename:
            path = os.path.join(dirpath, fname) 
            strg = open(path).read() 
            if re.search(pattern, strg):

                strg = strg.replace(oldstr, newstr) 
                f = open(path, 'w') 
                f.write(strg) 
                f.close()

1 个答案:

答案 0 :(得分:1)

最简单的改进:停止使用re,并将if re.search(pattern, strg):更改为if oldstr in strg:re不会在这里给您买任何东西(比简单的字符串搜索来查找固定字符串要贵得多)。

或者(更复杂),如果您知道文件的编码,则可以受益于mmap模块(特别是find方法)的使用,而不必加载将整个文件存储到内存中,并在字符串不太可能出现在输入中时对其进行解码;只需对搜索字符串进行预编码并搜索原始二进制数据即可。注意:这不适用于某些编码,在这种情况下,读取未对齐的原始字节可能会产生误报,但对于自同步编码(例如UTF-8)或单字节编码(例如ASCII,拉丁语- 1)。

最后,在重写文件时,请避免将其浪费在内存中,然后重写原始文件;如果文件大小超过物理RAM,除了使程序死(或运行缓慢)之外,这还意味着如果程序在开始重写文件后死了,那么您将永远丢失数据。 tempfile模块可用于在与原始文件相同的dir中创建一个临时文件,您可以逐行读取并随时替换,写入临时文件直到完成。然后只需执行一次从临时文件到原始文件名的原子重命名,即可通过一次操作替换原始文件(确保它是新数据还是旧数据,而不是数据的某些中间版本)。

并行化可能会为您带来一些好处,但是如果您对旋转的磁盘进行操作,则I / O争用的危害更大,莫过于帮助。我唯一一次看到可靠的改进是在具有足够带宽的网络文件系统上,但是有足够的延迟来保证并行运行I / O操作。