我有多个3 GB制表符分隔文件.每个文件中有2000万行.所有行必须独立处理,任何两行之间没有关系.
我的问题是,什么会更快A.使用以下方式逐行阅读:
with open() as infile:
for line in infile:
或者B.以块的形式将文件读入内存并进行处理,一次说250 MB?
处理不是很复杂,我只是将column1中的值抓到List1,将column2抓到List2等.可能需要一起添加一些列值.
我在具有30GB内存的Linux机器上使用python 2.7. ASCII文本.
有什么方法可以加速并行?现在我正在使用前一种方法,而且过程非常缓慢.使用任何CSVReader模块都可以提供帮助吗?
我不必在python中使用它,任何其他语言或数据库使用的想法都是受欢迎的.
解决方法:
听起来你的代码是I / O绑定的.这意味着多处理不会有所帮助 – 如果您花费90%的时间从磁盘读取数据,那么在下次读取时等待额外的7个进程对任何事情都无济于事.
而且,虽然使用CSV读取模块(无论是stdlib的csv还是像NumPy或Pandas这样的东西)可能是一个简单的好主意,但它不太可能在性能上有很大的不同.
不过,值得检查一下你是否真的受I / O限制,而不仅仅是猜测.运行程序,查看CPU使用率是接近0%还是接近100%或核心.做Amadan在评论中提出的建议,并运行你的程序,只需通过处理,看看是否会减少5%的时间或70%.您甚至可能想尝试与os.open和os.read(1024 * 1024)之类的循环进行比较,看看是否更快.
由于你使用Python 2.x,Python依靠C stdio库来猜测一次缓冲多少,因此可能值得强制缓冲更多.最简单的方法是对某些大型bufsize使用readlines(bufsize). (您可以尝试不同的数字并测量它们以查看峰值的位置.根据我的经验,通常64K-8MB的任何东西大致相同,但取决于您的系统可能会有所不同 – 特别是如果您是,例如,阅读关闭网络文件系统,吞吐量很大,但延迟时间很长,淹没了实际物理驱动器的吞吐量与延迟以及操作系统的缓存.)
所以,例如:
bufsize = 65536
with open(path) as infile:
while True:
lines = infile.readlines(bufsize)
if not lines:
break
for line in lines:
process(line)
同时,假设您使用的是64位系统,您可能想尝试使用mmap
而不是首先读取文件.这当然不能保证更好,但可能会更好,具体取决于您的系统.例如:
with open(path) as infile:
m = mmap.mmap(infile, 0, access=mmap.ACCESS_READ)
Python mmap是一种奇怪的对象 – 它同时就像一个str,就像一个文件一样,所以你可以,例如,手动迭代扫描换行,或者你可以像对待文件那样调用readline.这两个将从Python中进行更多的处理,而不是将文件作为行或批处理读取线进行迭代(因为在C中的循环现在是纯Python …虽然也许你可以用re或者简单的Cython扩展来解决这个问题?)…但操作系统的I / O优势知道你正在使用映射做什么可能会淹没CPU的劣势.
不幸的是,Python没有公开你用来调整东西的madvise
调用,试图在C中优化它(例如,显式设置MADV_SEQUENTIAL而不是让内核猜测,或强制透明的大页面) – 但你实际上可以ctypes libc的功能.