首页 > 解决方案 > 有没有办法比我的脚本更快地读取 GB 大小的文本文件?

问题描述

我编写了一个 python 脚本来快速读取和替换文件夹中的多个文本文件,以 Gb 为单位。有没有办法比我的脚本更快地做到这一点?当这个脚本运行时,是否可以为这个脚本指定几个 cpu 核心?

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

标签: pythonreplace

解决方案


最简单的改进:停止使用reif re.search(pattern, strg):改为if oldstr in strg:re在这里不会给你买任何东西(它比简单的字符串搜索更昂贵)。

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

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

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


推荐阅读