Python如何给你的程序做性能测试


Posted in Python onJuly 29, 2020

问题

你想测试你的程序运行所花费的时间并做性能测试。

解决方案

如果你只是简单的想测试下你的程序整体花费的时间, 通常使用Unix时间函数就行了,比如:

bash % time python3 someprogram.py
real 0m13.937s
user 0m12.162s
sys 0m0.098s
bash %

如果你还需要一个程序各个细节的详细报告,可以使用 cProfile 模块:

bash % python3 -m cProfile someprogram.py
     859647 function calls in 16.016 CPU seconds

  Ordered by: standard name

  ncalls tottime percall cumtime percall filename:lineno(function)
  263169  0.080  0.000  0.080  0.000 someprogram.py:16(frange)
   513  0.001  0.000  0.002  0.000 someprogram.py:30(generate_mandel)
  262656  0.194  0.000  15.295  0.000 someprogram.py:32(<genexpr>)
    1  0.036  0.036  16.077  16.077 someprogram.py:4(<module>)
  262144  15.021  0.000  15.021  0.000 someprogram.py:4(in_mandelbrot)
    1  0.000  0.000  0.000  0.000 os.py:746(urandom)
    1  0.000  0.000  0.000  0.000 png.py:1056(_readable)
    1  0.000  0.000  0.000  0.000 png.py:1073(Reader)
    1  0.227  0.227  0.438  0.438 png.py:163(<module>)
   512  0.010  0.000  0.010  0.000 png.py:200(group)
  ...
bash %

不过通常情况是介于这两个极端之间。比如你已经知道代码运行时在少数几个函数中花费了绝大部分时间。 对于这些函数的性能测试,可以使用一个简单的装饰器:

# timethis.py

import time
from functools import wraps

def timethis(func):
  @wraps(func)
  def wrapper(*args, **kwargs):
    start = time.perf_counter()
    r = func(*args, **kwargs)
    end = time.perf_counter()
    print('{}.{} : {}'.format(func.__module__, func.__name__, end - start))
    return r
  return wrapper

要使用这个装饰器,只需要将其放置在你要进行性能测试的函数定义前即可,比如:

>>> @timethis
... def countdown(n):
...   while n > 0:
...       n -= 1
...
>>> countdown(10000000)
__main__.countdown : 0.803001880645752
>>>

要测试某个代码块运行时间,你可以定义一个上下文管理器,例如:

from contextlib import contextmanager

@contextmanager
def timeblock(label):
  start = time.perf_counter()
  try:
    yield
  finally:
    end = time.perf_counter()
    print('{} : {}'.format(label, end - start))

下面是使用这个上下文管理器的例子:

>>> with timeblock('counting'):
...   n = 10000000
...   while n > 0:
...       n -= 1
...
counting : 1.5551159381866455
>>>

对于测试很小的代码片段运行性能,使用 timeit 模块会很方便,例如:

>>> from timeit import timeit
>>> timeit('math.sqrt(2)', 'import math')
0.1432319980012835
>>> timeit('sqrt(2)', 'from math import sqrt')
0.10836604500218527
>>>

timeit 会执行第一个参数中语句100万次并计算运行时间。 第二个参数是运行测试之前配置环境。如果你想改变循环执行次数, 可以像下面这样设置 number 参数的值:

>>> timeit('math.sqrt(2)', 'import math', number=10000000)
1.434852126003534
>>> timeit('sqrt(2)', 'from math import sqrt', number=10000000)
1.0270336690009572
>>>

讨论

当执行性能测试的时候,需要注意的是你获取的结果都是近似值。 time.perf_counter() 函数会在给定平台上获取最高精度的计时值。 不过,它仍然还是基于时钟时间,很多因素会影响到它的精确度,比如机器负载。 如果你对于执行时间更感兴趣,使用 time.process_time() 来代替它。例如:

from functools import wraps
def timethis(func):
  @wraps(func)
  def wrapper(*args, **kwargs):
    start = time.process_time()
    r = func(*args, **kwargs)
    end = time.process_time()
    print('{}.{} : {}'.format(func.__module__, func.__name__, end - start))
    return r
  return wrapper

最后,如果你想进行更深入的性能分析,那么你需要详细阅读 time 、timeit 和其他相关模块的文档。 这样你可以理解和平台相关的差异以及一些其他陷阱。 还可以参考13.13小节中相关的一个创建计时器类的例子。

以上就是Python如何给你的程序做性能测试的详细内容,更多关于Python做性能测试的资料请关注三水点靠木其它相关文章!

Python 相关文章推荐
Python中的并发编程实例
Jul 07 Python
python计算对角线有理函数插值的方法
May 07 Python
Django实现图片文字同时提交的方法
May 26 Python
分析用Python脚本关闭文件操作的机制
Jun 28 Python
python学习之编写查询ip程序
Feb 27 Python
tensorflow中next_batch的具体使用
Feb 02 Python
在python中利用numpy求解多项式以及多项式拟合的方法
Jul 03 Python
django fernet fields字段加密实践详解
Aug 12 Python
pyecharts绘制中国2020肺炎疫情地图的实例代码
Feb 12 Python
基于python 将列表作为参数传入函数时的测试与理解
Jun 05 Python
BeautifulSoup获取指定class样式的div的实现
Dec 07 Python
详解解Django 多对多表关系的三种创建方式
Aug 23 Python
Python3爬虫中关于中文分词的详解
Jul 29 #Python
Python3爬虫中pyspider的安装步骤
Jul 29 #Python
关于Python3爬虫利器Appium的安装步骤
Jul 29 #Python
Python3爬虫mitmproxy的安装步骤
Jul 29 #Python
Python使用jpype模块调用jar包过程解析
Jul 29 #Python
Python 防止死锁的方法
Jul 29 #Python
Python定义一个Actor任务
Jul 29 #Python
You might like
利用phpExcel实现Excel数据的导入导出(全步骤详细解析)
2013/11/26 PHP
ECMall支持SSL连接邮件服务器的配置方法详解
2014/05/19 PHP
Zend Framework动作助手(Zend_Controller_Action_Helper)用法详解
2016/03/05 PHP
PHP的全局错误处理详解
2016/04/25 PHP
yii2 commands模式以及配置crontab定时任务的方法
2017/08/19 PHP
PHP实现用session来实现记录用户登陆信息
2018/10/15 PHP
浅析PHP反序列化中过滤函数使用不当导致的对象注入问题
2020/02/15 PHP
页面右下角弹出提示框示例代码js版
2013/08/02 Javascript
各种页面定时跳转(倒计时跳转)代码总结
2013/10/24 Javascript
jQuery.prop() 使用详解
2015/07/19 Javascript
JQueryEasyUI框架下的combobox的取值和绑定的方法
2017/01/22 Javascript
canvas滤镜效果实现代码
2017/02/06 Javascript
详谈js对url进行编码和解码(三种方式的区别)
2017/08/16 Javascript
karma+webpack搭建vue单元测试环境的方法示例
2018/05/24 Javascript
vue实现简单的星级评分组件源码
2018/11/16 Javascript
vue中获取滚动table的可视页面宽度调整表头与列对齐(每列宽度不都相同)
2019/08/17 Javascript
vue深度监听(监听对象和数组的改变)与立即执行监听实例
2020/09/04 Javascript
[54:08]LGD女子刀塔学院 DOTA2炼金术士教学
2014/01/09 DOTA
[01:43]深扒TI7聊天轮盘语音出处4
2017/05/11 DOTA
Unicode和Python的中文处理
2017/03/19 Python
在python中只选取列表中某一纵列的方法
2018/11/28 Python
python for循环remove同一个list过程解析
2019/08/14 Python
Django 实现xadmin后台菜单改为中文
2019/11/15 Python
python基于opencv检测程序运行效率
2019/12/28 Python
pytorch随机采样操作SubsetRandomSampler()
2020/07/07 Python
Scrapy中如何向Spider传入参数的方法实现
2020/09/28 Python
HTML5获取当前地理位置并在百度地图上展示的实例
2020/07/10 HTML / CSS
C语言如何决定使用那种整数类型
2016/11/26 面试题
放弃遗产继承公证书
2015/01/26 职场文书
少先队工作总结2015
2015/05/13 职场文书
邓小平文选读书笔记
2015/06/29 职场文书
2016年小学优秀班主任事迹材料
2016/02/29 职场文书
AudioContext 实现音频可视化(web技术分享)
2022/02/24 Javascript
Python可视化学习之seaborn调色盘
2022/02/24 Python
Python批量解压&压缩文件夹的示例代码
2022/04/04 Python
TS 类型兼容教程示例详解
2022/09/23 Javascript