python - 有没有办法比我的脚本更快地读取 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()
解决方案
最简单的改进:停止使用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 操作。
推荐阅读
- git - Git 分支策略 - 拉取请求创建合并提交,使分支看起来不同,而文件相同
- c# - 动态获取一个 DbSet
按实体类名称 - EF Core - python - Pandas 中的以下命令有什么作用?
- swift - 使用 present 创建时,防止 ViewController 在后台堆叠
- arrays - 是否有理由使用 &[data] 而不仅仅是 [data]?
- java - /data/local/tmp/test 错误=13,权限被拒绝
- python - 根据中位数和标准差去除异常值
- javascript - litelement - 处理点击离开事件
- python - 追加到列表每次都会换行?
- c# - 使用 SignalR 和 ASP.NET MVC 5.2 在长时间运行的操作完成时发送消息