《Python高性能编程》——2.10 用heapy调查堆上的对象
本节书摘来自异步社区《Python高性能编程》一书中的第2章,第2.10节,作者[美] 戈雷利克 (Micha Gorelick),胡世杰,徐旭彬 译,更多章节内容可以访问云栖社区“异步社区”公众号查看。
2.10 用heapy调查堆上的对象Guppy项目有一个内存堆的调查工具叫作heapy,可以让你查看Python堆中对象的数量以及每个对象的大小。当你需要知道某一时刻有多少对象被使用以及它们是否被垃圾收集时,你尤其需要这种深入解释器内部去了解内存中实际内容的能力。如果你受困于内存泄漏(可能由于你的对象的引用隐藏于一个复杂系统中),那么这个工具能帮你找到问题的关键点。
当你在审查你的代码,看它是否如你预期那样生成对象时,你会发现这个工具非常有用——结果很可能令你吃惊,并为你带来新的优化方向。
为了使用heapy,你需要用命令pip install guppy安装guppy包。
例2-12的代码是Julia代码的一个略有修改的版本。calc_pure_python使用了堆对象hpy,我们在三个地方打印堆的内容。
例2-12 用heapy查看代码运行时对象数量的变化
def calc_pure_python(draw_output, desired_width, max_iterations): while xcoord x2: x.append(xcoord) xcoord += x_step from guppy import hpy; hp = hpy() print "heapy after creating y and x lists of floats" h = hp.heap() print h print zs = [] cs = [] for ycoord in y: for xcoord in x: zs.append(complex(xcoord, ycoord)) cs.append(complex(c_real, c_imag)) print "heapy after creating zs and cs using complex numbers" h = hp.heap() print h print print "Length of x:", len(x) print "Total elements:", len(zs) start_time = time.time() output = calculate_z_serial_purepython(max_iterations, zs, cs) end_time = time.time() secs = end_time - start_time print calculate_z_serial_purepython.func_name + " took", secs, "seconds" print print "heapy after calling calculate_z_serial_purepython" h = hp.heap() print h print
例2-13的输出显示了内存的使用在创建zs和cs列表后变得有趣:它增长了大约80MB,因为2000000个复数对象消耗了64000000字节。这些复数对象占据了目前使用的大多数内存。如果你想要优化这个程序的内存用量,这个结果可用于揭示目前保存的对象数量以及它们总共占用的空间。
例2-13 heapy输出显示了我们代码执行时每一个主要阶段的对象总数
$ python julia1_guppy.py heapy after creating y and x lists of floats Partition of a set of 27293 objects. Total size = 3416032 bytes. Index Count % Size % Cumulative % Kind (class / dict of class) 0 10960 40 1050376 31 1050376 31 str 1 5768 21 465016 14 1515392 44 tuple 2 199 1 210856 6 1726248 51 dict of type 3 72 0 206784 6 1933032 57 dict of module 4 1592 6 203776 6 2136808 63 types.CodeType 5 313 1 201304 6 2338112 68 dict (no owner) 6 1557 6 186840 5 2524952 74 function 7 199 1 177008 5 2701960 79 type 8 124 0 135328 4 2837288 83 dict of class 9 1045 4 83600 2 2920888 86 __builtin__.wrapper_descriptor 91 more rows. Type e.g. _.more to view. heapy after creating zs and cs using complex numbers Partition of a set of 2027301 objects. Total size = 83671256 bytes. Index Count % Size % Cumulative % Kind (class / dict of class) 0 2000000 99 6400000 76 64000000 76 complex 1 185 0 16295368 19 80295368 96 list 2 10962 1 1050504 1 81345872 97 str 3 5767 0 464952 1 81810824 98 tuple 4 199 0 210856 0 82021680 98 dict of type 5 72 0 206784 0 82228464 98 dict of module 6 1592 0 203776 0 82432240 99 types.CodeType 7 319 0 202984 0 82635224 99 dict (no owner) 8 1556 0 186720 0 82821944 99 function 9 199 0 177008 0 82998952 99 type 92 more rows. Type e.g. _.more to view. Length of x: 1000 Total elements: 1000000 calculate_z_serial_purepython took 13.2436609268 seconds heapy after calling calculate_z_serial_purepython Partition of a set of 2127696 objects. Total size = 94207376 bytes. Index Count % Size % Cumulative % Kind (class / dict of class) 0 2000000 94 64000000 68 64000000 68 complex 1 186 0 24421904 26 88421904 94 list 2 100965 5 2423160 3 90845064 96 int 3 10962 1 1050504 1 91895568 98 str 4 5767 0 464952 0 92360520 98 tuple 5 199 0 210856 0 92571376 98 dict of type 6 72 0 206784 0 92778160 98 dict of module 7 1592 0 203776 0 92981936 99 types.CodeType 8 319 0 202984 0 93184920 99 dict (no owner) 9 1556 0 186720 0 93371640 99 function 92 more rows. Type e.g. _.more to view.
第三段显示了在计算完Julia集合后,我们占用了94MB的内存。除了之前的复数,我们现在还保存了大量的整数,列表中的项目也变多了。
hpy.setrelheap()可以用来创建一个内存断点,当后续调用hpy.heap()时就会产生一个跟这个断点的差额。这样你就可以略过断点前由Python内部操作导致的内存分配。
Python函数是所谓的第一类对象(First-Class Object)是什么鬼? 之前写过一篇关于装饰器的文章,虽然写得还算不错,但是也有不少同学表示没看懂,我大概分析了其中的原因,主要问题是他们不理解函数,因为Python中的函数不同于其它语言。
【python可视化】python编码规范、标准库与扩展库对象的导入与使用 代码布局和排版在很大程度上决定了代码可读性的好坏,变量名、函数名、类名等标识符名称也会对代码的可读性带来一定的影响。一个好的python代码不仅应该是正确的,还应该是漂亮的、优雅的。
异步社区 异步社区(www.epubit.com)是人民邮电出版社旗下IT专业图书旗舰社区,也是国内领先的IT专业图书社区,致力于优质学习内容的出版和分享,实现了纸书电子书的同步上架,于2015年8月上线运营。公众号【异步图书】,每日赠送异步新书。
相关文章
- Python脚本扫描给定网段的MAC地址表(scapy或 python-nmap)
- Python脚本扫描给定网段的MAC地址表(scapy或 python-nmap)
- python安装python-lzf包,报错lzf_module.c:3:20: fatal error: Python.h: No such file or directory
- Python基础之:Python中的内部对象
- 【华为OD机试真题 python】演唱会【2022 Q4 | 200分】
- python⾯向对象编程-多态
- 小白,如何学好python,python爬虫入门教程(很详细)
- python ljust()、center() 、rjust() 字符串填充左中右对齐
- Python内置函数--sorted()
- Python类对象的JSON序列化处理
- python打印技巧
- Ubuntu 16.04 python和OpenCV安装
- 《Python面向对象编程指南》——2.8 __new__()方法和不可变对象
- 《Python Cookbook(第3版)中文版》——6.8 同关系型数据库进行交互
- [转]Python实现字符串反转的几种方法
- Python基础必掌握的字符串和字符数据操作
- Python 中的默认值是什么?
- Python AI 在几秒钟内为我生成了这些 Python 应用程序——它们有用吗?
- 《从问题到程序:用Python学编程和计算》——2.2 数据对象、计算和类型
- 3.python文件操作
- Python 常见问题 之 python 安装包下载安装速度慢 的 快速解决方法(之一)
- Python 基础 之 python 协程知识点整理,并实现一个简单 gevent 的协程并发图片下载的应用
- Python 工具 之 Windows 上 python 虚拟环境的搭建与简单使用的相关说明
- Unity 工具 之 报错 Jenkins 执行/调用 Python 脚本,报错提示 ‘python‘ 不是内部或外部命令,也不是可运行的程序或批处理文件
- python第四十八课——类函数和对象函数
- python文件读写模式 --- r,w,a,r+,w+,a+,rb,wb
- Python - 3.6 学习第一天
- 学习笔记(20):Python网络编程&并发编程-互斥锁与join的区别
- Python:类和对象的详细分析