如何使用Python标准库进行性能测试


Posted in Python onJune 25, 2019

Profile 和 cProfile

在 Python 标准库里面有两个模块可以用来做性能测试。

1. 一个是 Profile,它是一个纯 Python 的实现,所以会慢一些,如果你需要对模块进行拓展,那么这个模块比较合适。

2. 第二个是 cProfile,从名字就可以看出这是一个 C 语言的实现版,官方推荐在大多数情况下使用。
这两者的接口和数据的输出格式是完全一样的,你可以在这两者之间自由的切换,所以下面我们仅以 cProfile 为例进行介绍。

使用 cProfile 进行性能测试

在 cProfile 中,进行性能测试十分简单,只需调用 run 方法,并将需要测试的函数及参数传递给它即可,下面我们对fib(n) 进行性能测试。

import cProfile

def fib(n):
 if n == 0:
 return 0
 if n == 1:
 return 1
 return fib(n-1) + fib(n-2)

if __name__ == '__main__':
 cProfile.run('fib(30)')

性能测试的结果如下图

如何使用Python标准库进行性能测试

可以看到一共进行了 2692539 次函数调用,共耗时 0.815 秒。下面每一行对应于一个函数的调用情况,其中:

1. ncalls, 函数总共调用次数;
2. tottime, 这个函数调用总共花费时间;
3. percall, 每个调用的平均花费时间;
4. cumtime, 总共累计花费时间;
5. percall, 每个调用的平均累计时间;
6. filename:lineno(function), 对应函数信息。

所以从图中可以明显看到几乎的耗时都在fib上,而且函数调用数过多,这主要是因为函数是递归调用的,并且会产生很多冗余分支,所以程序需要进行优化。有两种方法进行改进,一是缓存fib(n)的信息,不需要每次都进行计算;二是将程序改为迭代式。

而对函数值进行缓存在 Python 3 里有一个简单的装饰器叫做lru_cache,可以自动的帮你缓存函数的值,而不需要自己手动存储。

import functools

@functools.lru_cache(maxsize=None)
def fib(n):
 if n == 0:
 return 0
 if n == 1:
 return 1
 return fib(n-1) + fib(n-2)

运行结果如下:

如何使用Python标准库进行性能测试

可以看到,fib 函数只调用了 31 次,几乎所有额外的调用都命中了缓存,远远小于前面的调用次数,运行时间也得到了相当明显的提升。同时使用下面的迭代版程序也运行得非常快,这里就不再展开。

def fib(n):
 prev, cur = 0, 1
 if n == 0:
 return prev
 if n == 1:
 return cur
 count = 1
 while count < n:
 count += 1
 prev, cur = cur, prev + cur
 return cur

除了前面提到的 run 方法外,还有一个叫做 runctx 的方法,允许提供一些上下文参数。例如前面的 cProfile.run('fib(30)') 可以改为cProfile.runctx('fib', globals(), {'n':30})最后的运行结果是相同的。

最后,除了直接打印到命令行的方式,run 和 runctx 可以通过第二个参数传递文件名的方式将输出结果写入文件。

使用 pstats 对显示进行控制

cProfile 虽然可以对程序进行简单的性能测试,但是当程序过大,调用函数很多的时候,就需要一些对测试结果进行过滤和排序的工具了,而 pstats 就是这样的一个工具。

# fib_profile.py
import cProfile
import pstats

for i in range(5):
 cProfile.run('fib(1000)', 'fib_profile_{}'.format(i))

stats = pstats.Stats('fib_profile_0')
for i in range(1, 5):
 stats.add('fib_profile_{}'.format(i))
stats.strip_dirs()
stats.sort_stats('cumulative')
stats.print_stats('fib')

上面的程序首先写入了多个测试结果,然后初始化了 stats,可以通过 stats 的 add 方法添加新的文件,pstats 会自动的将结果聚合起来;然后 strip_dirs 将会移除文件名前面的路径,只保留文件名;sort_stats 是对输出结果进行排序,也就是在前面所说的那几行里进行选择(具体的可参阅官方文档);最后的 print_stats 对结果进行输出,在这面可以对行进行过滤,比如上面的程序就只输出了包含 fib 的行;实际输出结果如下。

如何使用Python标准库进行性能测试

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python实现根据用户输入从电影网站获取影片信息的方法
Apr 07 Python
深入学习Python中的上下文管理器与else块
Aug 27 Python
Python实现句子翻译功能
Nov 14 Python
详解django三种文件下载方式
Apr 06 Python
用python处理图片实现图像中的像素访问
May 04 Python
Numpy中矩阵matrix读取一列的方法及数组和矩阵的相互转换实例
Jul 02 Python
Python 获取主机ip与hostname的方法
Dec 17 Python
Python pycharm 同时加载多个项目的方法
Jan 17 Python
利用Python实现微信找房机器人实例教程
Mar 10 Python
Python数据可视化:泊松分布详解
Dec 07 Python
Pytorch使用MNIST数据集实现基础GAN和DCGAN详解
Jan 10 Python
django xadmin action兼容自定义model权限教程
Mar 30 Python
python绘制评估优化算法性能的测试函数
Jun 25 #Python
Python基于机器学习方法实现的电影推荐系统实例详解
Jun 25 #Python
Python 中的参数传递、返回值、浅拷贝、深拷贝
Jun 25 #Python
pyqt5 删除layout中的所有widget方法
Jun 25 #Python
在Python中表示一个对象的方法
Jun 25 #Python
Python设置matplotlib.plot的坐标轴刻度间隔以及刻度范围
Jun 25 #Python
浅谈PyQt5 的帮助文档查找方法,可以查看每个类的方法
Jun 25 #Python
You might like
用PHP连接MySQL代码的参数说明
2008/06/07 PHP
在Windows下编译适用于PHP 5.2.12及5.2.13的eAccelerator.dll(附下载)
2010/05/04 PHP
关于file_get_contents返回为空或函数不可用的解决方案
2013/06/24 PHP
PHP面向对象程序设计方法实例详解
2016/12/24 PHP
js播放wav文件(源码)
2013/04/22 Javascript
ListBox实现上移,下移,左移,右移的简单实例
2014/02/13 Javascript
原生js获取宽高与jquery获取宽高的方法关系对比
2014/04/04 Javascript
原生js与jQuery实现简单的tab切换特效对比
2015/07/30 Javascript
分步解析JavaScript实现tab选项卡自动切换功能
2016/01/25 Javascript
angular4模块中给标签添加背景图的实现方法
2017/09/15 Javascript
echarts学习笔记之图表自适应问题详解
2017/11/22 Javascript
JavaScript数据结构之单链表和循环链表
2017/11/28 Javascript
Angular4编程之表单响应功能示例
2017/12/13 Javascript
Vue.js项目中管理每个页面的头部标签的两种方法
2018/06/25 Javascript
layui对工具条进行选择性的显示方法
2019/09/19 Javascript
js+html+css实现手动轮播和自动轮播
2020/12/30 Javascript
[03:10]2014DOTA2 TI马来劲旅Titan首战告捷目标只是8强
2014/07/10 DOTA
[46:25]DOTA2上海特级锦标赛主赛事日 - 4 败者组第五轮 MVP.Phx VS EG第二局
2016/03/05 DOTA
Python 过滤字符串的技巧,map与itertools.imap
2008/09/06 Python
Python 专题六 局部变量、全局变量global、导入模块变量
2017/03/20 Python
对python 数据处理中的LabelEncoder 和 OneHotEncoder详解
2018/07/11 Python
Python pygorithm模块用法示例【常见算法测试】
2018/08/16 Python
python opencv圆、椭圆与任意多边形的绘制实例详解
2020/02/06 Python
python实现IOU计算案例
2020/04/12 Python
通过案例解析python鸭子类型相关原理
2020/10/10 Python
详解Open Folder as PyCharm Project怎么添加的方法
2020/12/29 Python
CSS3 选择器 属性选择器介绍
2012/01/21 HTML / CSS
美体小铺美国官网:The Body Shop美国
2017/11/10 全球购物
美国定制钻石订婚戒指:Ritani
2017/12/08 全球购物
房地产推广策划方案
2014/05/19 职场文书
化妆品活动策划方案
2014/05/23 职场文书
教师个人自我评价
2015/03/04 职场文书
幼儿园教师个人工作总结2015
2015/05/12 职场文书
Flask response响应的具体使用
2021/07/15 Python
Linux中文件的基本属性介绍
2022/06/01 Servers
Android Canvas绘制文字横纵向对齐
2022/06/05 Java/Android