如何在Python中便宜地计算行数?
我需要在python中获得一个大文件(数十万行)的行数。 什么是记忆和时间最有效的方式?
目前我这样做:
def file_len(fname):
with open(fname) as f:
for i, l in enumerate(f):
pass
return i + 1
有没有可能做得更好?
你不能比这更好。
毕竟,任何解决方案都必须读取整个文件,找出有多少n
,并返回该结果。
没有阅读整个文件,你有没有更好的方法呢? 不确定...最好的解决方案将永远是I / O绑定的,最好的办法是确保你不使用不必要的内存,但看起来你已经覆盖了。
一条线可能非常快:
num_lines = sum(1 for line in open('myfile.txt'))
我相信内存映射文件将是最快的解决方案。 我尝试了四个函数:OP发布的函数( opcount
); 对文件中的行进行简单迭代( simplecount
); 带有内存映射mapcount
readline(mmap)( mapcount
); 以及由Mykola Kharechko( bufcount
)提供的缓冲读取解决方案。
我运行了五次函数,并计算了一个120万行文本文件的平均运行时间。
Windows XP,Python 2.5,2GB RAM,2 GHz AMD处理器
这是我的结果:
mapcount : 0.465599966049
simplecount : 0.756399965286
bufcount : 0.546800041199
opcount : 0.718600034714
编辑 :Python 2.6的数字:
mapcount : 0.471799945831
simplecount : 0.634400033951
bufcount : 0.468800067902
opcount : 0.602999973297
所以缓冲区读取策略似乎是Windows / Python 2.6中最快的
代码如下:
from __future__ import with_statement
import time
import mmap
import random
from collections import defaultdict
def mapcount(filename):
f = open(filename, "r+")
buf = mmap.mmap(f.fileno(), 0)
lines = 0
readline = buf.readline
while readline():
lines += 1
return lines
def simplecount(filename):
lines = 0
for line in open(filename):
lines += 1
return lines
def bufcount(filename):
f = open(filename)
lines = 0
buf_size = 1024 * 1024
read_f = f.read # loop optimization
buf = read_f(buf_size)
while buf:
lines += buf.count('n')
buf = read_f(buf_size)
return lines
def opcount(fname):
with open(fname) as f:
for i, l in enumerate(f):
pass
return i + 1
counts = defaultdict(list)
for i in range(5):
for func in [mapcount, simplecount, bufcount, opcount]:
start_time = time.time()
assert func("big_file.txt") == 1209138
counts[func].append(time.time() - start_time)
for key, vals in counts.items():
print key.__name__, ":", sum(vals) / float(len(vals))
链接地址: http://www.djcxy.com/p/31511.html