最近我一直在制作一个python脚本,用于从大型文本文件(> 1 GB)中提取数据.问题基本上总结为从文件中选择文本行,并从一些数组中搜索它们的字符串(此数组中最多可包含1000个字符串).这里的问题是我必须找到字符串的特定匹配项,并且该字符串在该文件中可能会出现无限次.此外,还需要一些解码和编码,这会进一步减慢脚本速度.
代码看起来像这样:
strings = [a for a in open('file.txt')]
with open("er.txt", "r") as f:
for chunk in f:
for s in strings
#do search, trimming, stripping ..
我的问题是:
有没有办法优化这个?我尝试了多处理,但它很少(或者至少我实现它的方式)这里的问题是这些块操作不是独立的,并且字符串列表可能在其中一个中被改变.
任何优化都会有所帮助(字符串搜索算法,文件读取等)我尽可能多地做了关于循环中断的事情,但它仍然运行得很慢.
解决方法:
如果您可以确切地知道字符串是如何以二进制(ASCII,UTF-8)编码的,那么您可以将整个文件一次性存储到内存中;它的行为与file.read()将获得的大型bytearray / bytes(或Python 2中的str)完全相同;然后这样的mmap对象可以通过str正则表达式(Python 2)或字节正则表达式(Python 3)进行搜索.
mmap是许多操作系统上最快的解决方案,因为只读映射意味着操作系统可以在页面准备好后自由映射;不需要交换空间,因为数据由文件支持.操作系统还可以直接映射缓冲区缓存中的数据,无需复制 – 因此在裸读时实现双赢.
例:
import mmap
import re
pattern = re.compile(b'the ultimate answer is ([0-9]+)')
with open("datafile.txt", "rb") as f:
# memory-map the file, size 0 means whole file
mm = mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ)
# PROT_READ only on *nix as the file is not writable
for match in pattern.finditer(mm):
# process match
print("The answer is {}".format(match.group(1).decode('ascii')))
mm.close()
现在,如果datafile.txt包含文本:
the ultimate answer is 42
在1千兆字节的数据中,该程序将成为最快的python解决方案之一:
The answer is 42
请注意,pattern.finditer
还接受可用于限制尝试匹配范围的开始和结束参数.
正如ivan_pozdeev所述,这需要1千兆字节的可用虚拟地址空间来映射千兆字节文件(但不一定是1千兆字节的RAM),这在32位进程中可能很难,但几乎可以肯定是“无问题” “在64位操作系统和CPU上.在32位进程上,该方法仍然有效,但您需要以较小的块映射大文件 – 因此现在操作系统和处理器的位真正重要.
标签:python,string,file-io 来源: https://codeday.me/bug/20190927/1822868.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。