网络编程
位置:首页>> 网络编程>> Python编程>> Python 循环读取数据内存不足的解决方案

Python 循环读取数据内存不足的解决方案

作者:ON_THE_WAY_FOREVER  发布时间:2022-02-25 17:32:17 

标签:Python,读取,数据,内存不足

看代码吧~


import gc
for x in list(locals().keys())[:]:
   del locals()[x]
# del all_s_x, AE, AE_split, x_ticks, split
gc.collect()

补充:Python读取大文件的"坑“与内存占用检测

python读写文件的api都很简单,一不留神就容易踩”坑“。笔者记录一次踩坑历程,并且给了一些总结,希望到大家在使用python的过程之中,能够避免一些可能产生隐患的代码。

1.read()与readlines():

随手搜索python读写文件的教程,很经常看到read()与readlines()这对函数。所以我们会常常看到如下代码:


with open(file_path, 'rb') as f:
   sha1Obj.update(f.read())

or


with open(file_path, 'rb') as f:
   for line in f.readlines():
       print(line)

这对方法在读取小文件时确实不会产生什么异常,但是一旦读取大文件,很容易会产生MemoryError,也就是内存溢出的问题。

Why Memory Error?

我们首先来看看这两个方法:

当默认参数size=-1时,read方法会读取直到EOF,当文件大小大于可用内存时,自然会发生内存溢出的错误。

Python 循环读取数据内存不足的解决方案

同样的,readlines会构造一个list。list而不是iter,所以所有的内容都会保存在内存之上,同样也会发生内存溢出的错误。

Python 循环读取数据内存不足的解决方案

2.正确的用法:

在实际运行的系统之中如果写出上述代码是十分危险的,这种”坑“十分隐蔽。所以接下来我们来了解一下正确用,正确的用法也很简单,依照API之中对函数的描述来进行对应的编码就OK了:

如果是二进制文件推荐用如下这种写法,可以自己指定缓冲区有多少byte。显然缓冲区越大,读取速度越快。


with open(file_path, 'rb') as f:
   while True:
       buf = f.read(1024)
       if buf:    
           sha1Obj.update(buf)
       else:
           break

而如果是文本文件,则可以用readline方法或直接迭代文件(python这里封装了一个语法糖,二者的内生逻辑一致,不过显然迭代文件的写法更pythonic )每次读取一行,效率是比较低的。笔者简单测试了一下,在3G文件之下,大概性能和前者差了20%.


with open(file_path, 'rb') as f:
   while True:
       line = f.readline()
       if buf:    
           print(line)
       else:
           break
with open(file_path, 'rb') as f:
   for line in f:
       print(line)

3.内存检测工具的介绍:

对于python代码的内存占用问题,对于代码进行内存监控十分必要。这里笔者这里推荐两个小工具来检测python代码的内存占用。


memory_profiler

首先先用pip安装memory_profiler


pip install memory_profiler

memory_profiler是利用python的装饰器工作的,所以我们需要在进行测试的函数上添加装饰器。


from hashlib import sha1
import sys
@profile
def my_func():
   sha1Obj = sha1()
   with open(sys.argv[1], 'rb') as f:
       while True:
           buf = f.read(10 * 1024 * 1024)
           if buf:
               sha1Obj.update(buf)
           else:
               break
   print(sha1Obj.hexdigest())
if __name__ == '__main__':
   my_func()

之后在运行代码时加上** -m memory_profiler**

就可以了解函数每一步代码的内存占用了

Python 循环读取数据内存不足的解决方案

guppy

依样画葫芦,仍然是通过pip先安装guppy


pip install guppy

之后可以在代码之中利用guppy直接打印出对应各种python类型(list、tuple、dict等)分别创建了多少对象,占用了多少内存。


from guppy import hpy
import sys
def my_func():
   mem = hpy()
   with open(sys.argv[1], 'rb') as f:
       while True:
           buf = f.read(10 * 1024 * 1024)
           if buf:
               print(mem.heap())
           else:
               break

如下图所示,可以看到打印出对应的内存占用数据:

Python 循环读取数据内存不足的解决方案

通过上述两种工具guppy与memory_profiler可以很好地来监控python代码运行时的内存占用问题。

4.小结:

python是一门崇尚简洁的语言,但是正是因为它的简洁反而更多了许多需要仔细推敲和思考的细节。希望大家在日常工作与学习之中也能多对一些细节进行总结,少踩一些不必要的“坑”。

来源:https://blog.csdn.net/weixin_41888257/article/details/107919638

0
投稿

猜你喜欢

  • 本文实例为大家分享了Python使用tkinter实现小时钟效果的具体代码,供大家参考,具体内容如下自己又调试了一下,分享一下# codin
  • Django带来了一个高级的聚合生成框架,它使得创建RSS和Atom feeds变得非常容易。什么是RSS? 什么是Atom?RSS和Ato
  • 首先我们有一个数据是一个mn的numpy矩阵现在我们希望能够进行给他加上一列变成一个m(n+1)的矩阵import numpy as npa
  • 人常常感受到色彩对自己心理的影响,这些影响总是在不知不觉中发挥作用,左右我们的情绪。色彩的心理效应发生在不同层次中。有些属直接的刺激,有些要
  • 一、概述公司新购了一批PC,准备把几个性能较优的PC升级为数据库服务器,替换老旧的机器。公司有套POS终端软件,后台数据存储是 MySQL
  • 2003年以来,网页的平均尺寸已经增长3倍。从2003到2008,网页的平均尺寸从93.7K增至312K,增幅233%。同时,在这5年之内,
  • 首先,我要在这里写上一些很官方的概念,意在说明面向对象是很具体化的,很实体的模式,不能让有些人看见“对象&rdq
  • Access数据库,同时操作大量记录(9500条以上)时报错。错误提示:Microsoft JET Database Engine 错误 &
  • 一、浏览器允许每个域名所包含的 cookie 数:Microsoft 指出 Internet Explorer 8 增加 cookie 限制
  • 最近在做一个站点时,需要生成静态页面,但是生成的静态页面中有些内容是需要动态获取的,怎不能每天生成一下吧。。 最后上网查了一下,再加上个要总
  • Mac版Python3安装/升级Mac系统自带Python,但都是2.X版本,非常老的版本了。如果我们需要安装Python3版本,怎么能快速
  • php的引用(就是在变量或者函数、对象等前面加上&符号),在PHP 中引用的意思是:不同的名字访问同一个变量内容。与C语言中的指针是
  • 1.SQL Server 2005中的存储过程并发问题问:我在SQL Server2005中遇到了并发问题。我持有车票的公共汽车上有一些空闲
  • 代码如下:Function htmll(mulu,htmlmulu,FileName,filefrom,htmla,htmlb,h
  • SQL Server数据库查询优化的常用方法总结:本文中,abigale代表查询字符串,ada代表数据表名,alice代表字段名。技巧一:问
  • 做项目的时候,一位同事导数据的时候,不小心把一个表中的数据全都搞重了,也就是说,这个表里所有的记录都有一条重复的。这个表的数据是千万级的,而
  • 本文实例为大家分享了Python OpenCV实现视频追踪的具体代码,供大家参考,具体内容如下1. MeanShift假设有一堆点集和一个圆
  • asp之家补充两点,以让大家看的更明白:一.什么是GUID?由于水平有限在看到这篇文章时,我并不了解什么是GUID,为了看懂文章当然先请教一
  • SVM支持向量机是建立于统计学习理论上的一种分类算法,适合与处理具备高维特征的数据集。SVM算法的数学原理相对比较复杂,好在由于SVM算法的
  • jquery的ajax请求方法:$.ajax({       &nbs
手机版 网络编程 asp之家 www.aspxhome.com