Python:用迭代器和生成器降低程序内存占用率
2017-01-12 09:54
190 查看
情况描述:用一个30行代码的python文件,处理300M的数据,用到的数据结构有:pandas.DataFrame(), list, dict,二重循环,处理完一次写入磁盘。
问题:内存占用率97%-99%,大约1.5G内存,执行时间超过12h。有什么办法可以降低python内存占用率,缩短执行时间吗?
建议一:用xrange生成器,替代range列表
因为rang是list,python在执行时会直接划一块内存来使用,而xrange是采用生成器 一个一个的执行。修改之后每个进程的占用内存数稳定在5M左右。内存占用降低的很明显。
range和xrange区别:(1) 类型不同,xrange是<type 'xrange'> (2) range返回包含所有元素的列表,xrange返回的是一个生成器,元素逐个被创建 (3) xrange不支持列表切片,进行多次next()迭代,每次都会从头开始。
建议二:多用迭代器,for elem in XXX
迭代器是一个实现了迭代器协议的对象,Python中的迭代器协议就是有next方法的对象会前进到下一结果,而在一系列结果的末尾是,则会引发StopIteration。迭代工具内部会在每次迭代时调用next方法,并且捕捉StopIteration异常来确定何时离开。
在Python中,for循环可以用于Python中的任何类型,包括列表、元祖等等,实际上,for循环可用于任何“可迭代对象”,这其实就是迭代器。
使用迭代器一个显而易见的好处就是:每次只从对象中读取一条数据,不会造成内存的过大开销。
案例:比如要逐行读取一个文件的内容,利用readlines()方法,我们可以这么写:
这样虽然可以工作,但不是最好的方法。因为他实际上是把文件一次加载到内存中,然后逐行打印。当文件很大时,这个方法的内存开销就很大了。利用file的迭代器,我们可以这样写:
这是最简单也是运行速度最快的写法,他并没显式的读取文件,而是利用迭代器每次读取下一行。
建议三:多用生成器yeild
yield 的作用就是把一个函数变成一个 generator。
函数在每次for循环中调用一次,执行到yeild返回迭代值。
函数状态会保存在本地变量中,直到下次被调用。
调用 fab(5) 不会执行 fab 函数,而是返回一个 iterable 对象!在 for 循环执行时,每次循环都会执行 fab 函数内部的代码,执行到 yield a 时,fab 函数就返回一个迭代值,下次迭代时,代码从 yield b 的下一条语句继续执行,而函数的本地变量看起来和上次中断执行前是完全一样的,于是函数继续执行,直到再次遇到 yield。
更具体案例:http://www.ibm.com/developerworks/cn/opensource/os-cn-python-yield/
问题:内存占用率97%-99%,大约1.5G内存,执行时间超过12h。有什么办法可以降低python内存占用率,缩短执行时间吗?
建议一:用xrange生成器,替代range列表
因为rang是list,python在执行时会直接划一块内存来使用,而xrange是采用生成器 一个一个的执行。修改之后每个进程的占用内存数稳定在5M左右。内存占用降低的很明显。
range和xrange区别:(1) 类型不同,xrange是<type 'xrange'> (2) range返回包含所有元素的列表,xrange返回的是一个生成器,元素逐个被创建 (3) xrange不支持列表切片,进行多次next()迭代,每次都会从头开始。
建议二:多用迭代器,for elem in XXX
迭代器是一个实现了迭代器协议的对象,Python中的迭代器协议就是有next方法的对象会前进到下一结果,而在一系列结果的末尾是,则会引发StopIteration。迭代工具内部会在每次迭代时调用next方法,并且捕捉StopIteration异常来确定何时离开。
在Python中,for循环可以用于Python中的任何类型,包括列表、元祖等等,实际上,for循环可用于任何“可迭代对象”,这其实就是迭代器。
使用迭代器一个显而易见的好处就是:每次只从对象中读取一条数据,不会造成内存的过大开销。
案例:比如要逐行读取一个文件的内容,利用readlines()方法,我们可以这么写:
1 2 | for line in open("test.txt").readlines(): print line |
1 2 | for line in open("test.txt"): #use file iterators print line |
建议三:多用生成器yeild
yield 的作用就是把一个函数变成一个 generator。
函数在每次for循环中调用一次,执行到yeild返回迭代值。
函数状态会保存在本地变量中,直到下次被调用。
1 23 | def fab(max): a,b = 0,1 while a < max: yield a a, b = b, a+b >>> for i in fab(20): ... print i,",", ... 0 , 1 , 1 , 2 , 3 , 5 , 8 , 13 , |
更具体案例:http://www.ibm.com/developerworks/cn/opensource/os-cn-python-yield/
相关文章推荐
- ·python·用生成器和迭代器实现自己的xrange
- ·python·用生成器和迭代器实现自己的xrange
- Python生成器和迭代器的关系
- python中迭代器和生成器
- python学习笔记之八:迭代器和生成器
- Python中的新型构造迭代器和简单生成器
- python中的迭代器与生成器
- python迭代器和生成器
- python迭代器和生成器
- 深入学习python(二) 迭代器(Iterator)和生成器(Generate)
- python·用生成器和迭代器实现自己的xrange
- 可爱的 Python: 迭代器和简单生成器
- Python迭代器与生成器(转)
- python 从yield 学习迭代器和生成器
- python中迭代器、列表解析、生成器的分析比较
- ·python·用生成器和迭代器实现自己的xrange
- Python的迭代器和生成器
- python中的迭代器与生成器 .
- Python 生成器与迭代器
- python中的迭代器与生成器详解