Python中读取大文件最快的方式是什么?
for line in files:? 这个是读取大文件最快的方式吗
Python中读取大文件最快的方式是什么?
with open(“file_name”, ‘r’) as input:
for line in input:
#process
这种真的非常慢啊
用 open() 配合 for line in file 迭代,这是内存效率最高的方式。Python 会按需读取,不会一次加载整个文件到内存。
with open('large_file.txt', 'r') as file:
for line in file:
process(line) # 逐行处理
如果文件是二进制或需要更细粒度的控制,可以用 read(size) 指定缓冲区大小:
with open('large_file.bin', 'rb') as file:
while chunk := file.read(8192): # 8KB 块
process(chunk)
对于纯文本且需要最快速度的场景,可以考虑 mmap 模块进行内存映射,让操作系统处理文件访问:
import mmap
with open('large_file.txt', 'r') as f:
with mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as mmap_obj:
# 可以像字符串一样操作,但数据仍在磁盘
data = mmap_obj.read()
简单总结:大文件就用迭代读取,别一次性全读进来。
100G 的文本。大家有好方式吗
mmap 的话,如何逐行读取呢
java 用 RandomAccessFile 读流的时候判断是\n 就行
肯定是文件流啊,然后一部分一部分的读取.
fs.createReadStream()
Java 有个根据指针读取的类
python 的 mmap 用行读取的方法?这样行吗,但是感觉还是很慢
with open(STAT_FILE, “r+b”) as f:
m=mmap.mmap(f.fileno(), 0, prot=mmap.PROT_READ)
while True:
line=m.readline()
if line == ‘’: break
print line.rstrip()
必须其他语言?
主要用来按行读取,然后 split,然后判断每个字段的编码,java 有这些? go 能满足?速度如何?
之所以慢,是因为要一次性把大文件读取到内存中。
使用流就行了,不是换语言能解决的
能给一个 python 流的例子吗
用 mmap,42m 读了 900 万条
不读,最快。
混合编码文本,单机多核心,pyspark 有逐行读取的案例?貌似在 api 里面没看到逐行读取的。。。。
太崇拜你了,哲学啊。
流读取会把不可见的分隔符给搞掉吧,比如 hive 的^A
你得先找到瓶颈啊,别瞎猜测是读取慢。来来来我给你验证下。
人工生成 1000 万行的文件
$ time python ./numbers.py > out
python ./numbers.py > out 6.37s user 0.24s system 89% cpu 7.395 total
逐行读取,然后输出到 stdout,也就 7s 钟
你说『 42m 读了 900 万条』,那么瓶颈我觉得大部分是出在你的处理逻辑上,管读取什么事情?
之前遇到过要读 10G 的文本,后来采取了先排序,分割,筛选一次,剩下差不多 2G,最后再进一步分段读取
用 Profile 去分析下耗时,优化要先分析,后优化。不能脑子一拍,肯定是 Python 大文件读取慢,就开始吭叽吭叽优化这个…
如果没有严格的上下文依赖的话,那么分割大文件,多线程读取,分割成几块就用几个线程,处理边界,数据结构最后再合并。
个人有个 25G 的文件用 mmap+多线程读取 5 分钟之内。
一定要用 mmap,因为这是最快的读文件方式。
1000 万行,每行 100 个字符,总共 1.9G 文件。Python 使用 mmap 每行都输出一下,需要
python ./numbers.py > out 8.81s user 6.27s system 33% cpu 45.088 total
如果是 100G 文件,也不过几分钟而已
还有怎么按行读取,遇到\n 就是新行啊。自己处理。
print 一行,没有其他逻辑处理。
10G,最后剩下 2G,这得多大的重复?丢失多少信息?
目前只是一行行的读,然后在每行中 split 出每一个段。mmap 貌似会吃掉这个分界符。这样后续我就不行了
你要按行读取必须从头开始扫描啊,找出 N 个回车换行符,快不起来的
with open(“test1.txt”,“r+b”) as f:
mm = mmap.mmap(f.fileno(),0)
while True:
line = mm.readline()
print line
if line == ‘’:
break
for v in line.split(’^A’):#这个分界符不起作用了
print v
m.close()
python 特殊符号不是这么转义的吧
什么类型“大”文件?后续怎么处理?
for line in input: 这个什么时候成了读取文件?
明明是遍历,open 的时候,文件就已经一次性读入内存了好吧。
你 print 是最慢的,把 print 去掉再试试
把代码贴出来,写错了吧😄
ctrl+v+a,这个弄错了,不好意思。
带有分隔符的文本文件,后续按照分隔符拆分。
好吧,我错了,只是想问如何才能更快的遍历
print 最慢?那我去掉。现在 for line in input 和 mmap 一起运行,觉得 mmap 还没有前者快?错觉?
with open(“test1.txt”,“r+b”) as f:
mm = mmap.mmap(f.fileno(),0,prot=mmap.PROT_READ)
while True:
line = mm.readline()
#print line
if line == ‘’:
break
for v in line.split(’^A’):
# print chardet.detect(v)
#print chardet.detect(v)[‘encoding’]
try:
if(chardet.detect(v)[‘encoding’] in [‘ascii’,‘none’,‘utf-8’,‘GB2312’,‘GBK’,‘Big5’,‘GB18030’,‘windows-1252’]):
print v.decode(chardet.detect(v)[‘encoding’]).encode(‘utf-8’)
else:
print v.decode(‘utf-8’).encode(‘utf-8’)
except:
with open(‘error_mmap.txt’,‘a’) as e:
e.write(line)
m.close()
纯文本文件处理,没什么区别吧,读写文件都是依赖操作系统。
“”常规文件操作需要从磁盘到页缓存再到用户主存的两次数据拷贝。而 mmap 操控文件,只需要从磁盘到用户主存的一次数据拷贝过程。说白了,mmap 的关键点是实现了用户空间和内核空间的数据直接交互而省去了空间不同数据不通的繁琐过程。因此 mmap 效率更高。“”
不知道也不要瞎讲,open 的时候文件并不会一次性读入内存。
mmap 更慢,多想想就知道,page fault 明显更多了,而且是 major page fault
目前看起来确实是 mmap 慢一些,当然我是两种都读一个文件,不知道是不是有影响。
python 里面,for line in input 就是逐行读取,print 慢
把需求讲具体,不同需求下做法必定不同。有时候是直接把全部文件直接载入内存最快,但有时候不是。甚至有时候不能使用 python,python 一定会成为瓶颈
按我经验
如果瓶颈在 IO 上的话,一次直接把所有内容都读进内存是最快的。
如果瓶颈在对内容细致地分析 /计算上的话,例如你要遍历 10G 文本里每个字节的话,那就必须得换语言才行。
如果瓶颈在于整体的处理速度的话,例如你要压缩一段文件。那这个就随便了,随便读取一部分处理完再继续读取就好。
逐行读取
分块读取
用 shell 脚本应该会很快很快
awk ?
你这个文本有多少行?
100G 的文本有点夸张。
先说读取
假如你的硬盘是 HDD,按照 120M/s 来算的话,读取 10G 需要 850s ;
如果你的硬盘是 SSD,按照 450M/s 来算的话,需要 230s ;
无论你怎么来,无论你用什么办法,应该是不会慢过这个速度多少的,也不会快过这个速度多少。
再说处理
100G 的文本估计 10 亿行应该是有的吧,这个数量真的是太大了,单线程处理的话,python 速度慢的缺点会被暴露无遗。
所以建议你多进程、多线程来处理。
你这个每行之间没有联系,可以靠多线程来提高性能。如果碰上那种每行之间互有联系的,只能换 c++慢慢跑,python 绝对不行。
像这类文件访存的效率问题都是处理时间和空间把戏。如果一个大文件要在短时间内随机访问上万次,用 mmap 应该是最好的。如果只是访问那么几次还不如 open write read。不过一般情况下无脑用 iostream 难道还不够快?
你这个瓶颈不在 IO,是你具体处理逻辑太慢。你做个 Profile 就知道了
不管什么语言,逐行读取肯定会慢一点,最快的方法是用 buff,
看要怎么处理,一般是分段分段(多少行到多少行,或者其他标识符号来记忆)提取后执行处理。
如果是要在 100GB 的文本里进行搜索……=v=呵呵呵呵呵呵呵呵
一次读取 4k 的数据,因为一般现在分区都是 4k 对齐的
这个问题其实有时候可以取巧处理的,比如用 parallel 工具,我觉得挺有意思,写了一篇文章,希望有帮助:
http://happy123.me/blog/2018/05/06/how-to-improve-performance-your-cmd-by-parallel/
目前只会 sed
这个可以试试。
with open(“file_name”, ‘r’) as input:
for line in input:
#process
我记得这种就是流式读取的啊???


