读取大文件,最快的方式是什么?

2018-05-05 07:51:25 +08:00
 sjmcefc2

for line in files:? 这个是读取大文件最快的方式吗

12390 次点击
所在节点    Python
54 条回复
dychenyi
2018-05-05 09:56:20 +08:00
如果没有严格的上下文依赖的话,那么分割大文件,多线程读取,分割成几块就用几个线程,处理边界,数据结构最后再合并。
个人有个 25G 的文件用 mmap+多线程读取 5 分钟之内。
一定要用 mmap,因为这是最快的读文件方式。
swulling
2018-05-05 09:57:07 +08:00
1000 万行,每行 100 个字符,总共 1.9G 文件。Python 使用 mmap 每行都输出一下,需要
python ./numbers.py > out 8.81s user 6.27s system 33% cpu 45.088 total

如果是 100G 文件,也不过几分钟而已
dychenyi
2018-05-05 09:58:12 +08:00
还有怎么按行读取,遇到\n 就是新行啊。自己处理。
sjmcefc2
2018-05-05 10:18:33 +08:00
@swulling print 一行,没有其他逻辑处理。

@crayygy 10G,最后剩下 2G,这得多大的重复?丢失多少信息?

@swulling 目前只是一行行的读,然后在每行中 split 出每一个段。mmap 貌似会吃掉这个分界符。这样后续我就不行了
tabris17
2018-05-05 10:20:59 +08:00
你要按行读取必须从头开始扫描啊,找出 N 个回车换行符,快不起来的
sjmcefc2
2018-05-05 10:21:42 +08:00
@dychenyi 按行读取没啥问题,就是貌似 mmap 之后,把我的分界符号吃掉了呢
sjmcefc2
2018-05-05 10:25:00 +08:00
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()
widewing
2018-05-05 11:26:06 +08:00
@sjmcefc2 python 特殊符号不是这么转义的吧
ioth
2018-05-05 11:30:15 +08:00
什么类型“大”文件?后续怎么处理?
crb912
2018-05-05 11:58:37 +08:00
for line in input: 这个什么时候成了读取文件?

明明是遍历,open 的时候,文件就已经一次性读入内存了好吧。
silymore
2018-05-05 12:55:54 +08:00
@sjmcefc2 你 print 是最慢的,把 print 去掉再试试
swulling
2018-05-05 13:02:09 +08:00
@sjmcefc2 把代码贴出来,写错了吧😄
sjmcefc2
2018-05-05 13:23:10 +08:00
@widewing ctrl+v+a,这个弄错了,不好意思。
@ioth 带有分隔符的文本文件,后续按照分隔符拆分。
@crb912 好吧,我错了,只是想问如何才能更快的遍历

@silymore 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()
ioth
2018-05-05 14:11:58 +08:00
纯文本文件处理,没什么区别吧,读写文件都是依赖操作系统。
dychenyi
2018-05-05 15:29:01 +08:00
@ioth “”常规文件操作需要从磁盘到页缓存再到用户主存的两次数据拷贝。而 mmap 操控文件,只需要从磁盘到用户主存的一次数据拷贝过程。说白了,mmap 的关键点是实现了用户空间和内核空间的数据直接交互而省去了空间不同数据不通的繁琐过程。因此 mmap 效率更高。“”
zhicheng
2018-05-05 16:54:28 +08:00
不知道也不要瞎讲,open 的时候文件并不会一次性读入内存。
fakevam
2018-05-05 17:39:28 +08:00
mmap 更慢,多想想就知道,page fault 明显更多了,而且是 major page fault
sjmcefc2
2018-05-05 17:43:39 +08:00
@fakevam 目前看起来确实是 mmap 慢一些,当然我是两种都读一个文件,不知道是不是有影响。
anjiannian
2018-05-05 18:50:32 +08:00
@sjmcefc2 python 里面,for line in input 就是逐行读取,print 慢
AX5N
2018-05-05 19:07:49 +08:00
把需求讲具体,不同需求下做法必定不同。有时候是直接把全部文件直接载入内存最快,但有时候不是。甚至有时候不能使用 python,python 一定会成为瓶颈

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/452267

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX