【问题标题】:Is there a way to read GB size text files faster than my script?有没有办法比我的脚本更快地读取 GB 大小的文本文件?
【发布时间】:2020-01-22 06:05:33
【问题描述】:

我编写了一个 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()

【问题讨论】:

  • 如果你在linux上,你可以使用sed
  • @sshashank124 以前我使用了一个 sed 脚本,但它比这个 python 脚本慢。我知道 python 脚本比 bash 脚本要快。
  • @sshashank124 #!/bin/bash cd "/root/tmp" sed -i -e 's/"//g' *.TXT rm *.TXTe
  • @Sushant 我不知道在给定链接中使用哪个是正确的?

标签: python replace


【解决方案1】:

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

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

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

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

【讨论】:

  • 它们是简单的文本文件(我认为是 UTF-8),我不知道如何修改我的代码以在您提到的缺少 RAM 的情况下工作?
  • @SandunDayananda:查看example code 以获得the mmap module。这并不是特别困难,只是从打开的文件到 mmap.mmap 对象的一些样板,然后以非复制方式使用所述对象(例如,不要切片它,它会复制,但是 memoryviews 或find 方法无需复制即可工作)。
猜你喜欢
  • 2020-05-08
  • 2015-08-07
  • 2020-05-01
  • 2023-01-29
  • 1970-01-01
  • 2013-02-03
  • 2022-08-04
  • 2011-04-20
  • 2020-11-17
相关资源
最近更新 更多