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读文件保存到字典,修改字典并写入新文件的实例
Apr 23 Python
Python3实现将本地JSON大数据文件写入MySQL数据库的方法
Jun 13 Python
Flask框架Jinjia模板常用语法总结
Jul 19 Python
python实现远程控制电脑
May 23 Python
浅析Python与Mongodb数据库之间的操作方法
Jul 01 Python
简单了解Django ContentType内置组件
Jul 23 Python
python3 常见解密加密算法实例分析【base64、MD5等】
Dec 19 Python
Selenium 滚动页面至元素可见的方法
Mar 18 Python
Python常见反爬虫机制解决方案
Jun 01 Python
关于python tushare Tkinter构建的简单股票可视化查询系统(Beta v0.13)
Oct 19 Python
python切片作为占位符使用实例讲解
Feb 17 Python
python+selenium小米商城红米K40手机自动抢购的示例代码
Mar 24 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
解析如何在PHP下载文件名中解决乱码的问题
2013/06/20 PHP
PHP URL路由类实例
2013/11/12 PHP
PHP实现批量删除(封装)
2017/04/28 PHP
使用JQuery和CSS模拟超链接的用户单击事件的实现代码
2012/05/23 Javascript
JavaScript高级程序设计 阅读笔记(十八) js跨平台的事件
2012/08/14 Javascript
只需20行代码就可以写出CSS覆盖率测试脚本
2013/04/24 Javascript
js获取指定日期前后的日期代码
2013/08/20 Javascript
js获取某元素的class里面的css属性值代码
2014/01/16 Javascript
快速学习jQuery插件 jquery.validate.js表单验证插件使用方法
2015/12/01 Javascript
JavaScript实现无穷滚动加载数据
2017/05/06 Javascript
原生JS实现网页手机音乐播放器 歌词同步播放的示例
2018/02/02 Javascript
Vue 中对图片地址进行拼接的方法
2018/09/03 Javascript
20个必会的JavaScript面试题(小结)
2019/07/02 Javascript
详解Nuxt.js中使用Element-UI填坑
2019/09/06 Javascript
小程序新版订阅消息模板消息
2019/12/31 Javascript
vue组件添加事件@click.native操作
2020/10/30 Javascript
Python守护进程和脚本单例运行详解
2017/01/06 Python
python 3.6.2 安装配置方法图文教程
2018/09/18 Python
python 限制函数执行时间,自己实现timeout的实例
2019/01/12 Python
Python检查ping终端的方法
2019/01/26 Python
python解析多层json操作示例
2019/12/30 Python
pytorch实现onehot编码转为普通label标签
2020/01/02 Python
TensorFlow 输出checkpoint 中的变量名与变量值方式
2020/02/11 Python
python如何代码集体右移
2020/07/20 Python
python实现人工蜂群算法
2020/09/18 Python
Python字符串对齐、删除字符串不需要的内容以及格式化打印字符
2021/01/23 Python
Matlab使用Plot函数实现数据动态显示方法总结
2021/02/25 Python
HTML5 Web 存储详解
2016/09/16 HTML / CSS
美国户外服装和装备购物网站:Outland USA
2020/03/22 全球购物
Linux中如何设置Java环境变量(Ubuntu)
2016/07/24 面试题
租房协议书怎么写
2014/04/10 职场文书
2014年图书馆工作总结
2014/11/25 职场文书
三好学生事迹材料
2014/12/24 职场文书
体育教师教学随笔
2015/08/15 职场文书
python Django框架快速入门教程(后台管理)
2021/07/21 Python
用python基于appium模块开发一个自动收取能量的小助手
2021/09/25 Python