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连接mysql实例分享
Oct 09 Python
mac安装pytorch及系统的numpy更新方法
Jul 26 Python
python之Flask实现简单登录功能的示例代码
Dec 24 Python
python中报错&quot;json.decoder.JSONDecodeError: Expecting value:&quot;的解决
Apr 29 Python
python中比较两个列表的实例方法
Jul 04 Python
对Python生成器、装饰器、递归的使用详解
Jul 19 Python
利用anaconda作为python的依赖库管理方法
Aug 13 Python
详解基于python-django框架的支付宝支付案例
Sep 23 Python
通过python3实现投票功能代码实例
Sep 26 Python
python 字典的打印实现
Sep 26 Python
Django中F函数的使用示例代码详解
Jul 06 Python
Django中celery的使用项目实例
Jul 07 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判断字符以及字符串的包含方法属性
2008/08/30 PHP
PHP 学习路线与时间表
2010/02/21 PHP
php 数组的一个悲剧?
2011/05/11 PHP
php+mysql实现无限级分类
2015/11/11 PHP
php打开本地exe程序,js打开本地exe应用程序,并传递相关参数方法
2018/02/06 PHP
改善你的jQuery的25个步骤 千倍级效率提升
2010/02/11 Javascript
script标签属性用type还是language
2015/01/21 Javascript
jQuery树形下拉菜单特效代码分享
2015/08/15 Javascript
js实现搜索框关键字智能匹配代码
2020/03/26 Javascript
VUEJS实战之构建基础并渲染出列表(1)
2016/06/13 Javascript
Bootbox将后台JSON数据填充Form表单的实例代码
2018/09/10 Javascript
js自定义input文件上传样式
2018/10/26 Javascript
傻瓜式vuex语法糖kiss-vuex整理
2018/12/21 Javascript
通过js给网页加上水印背景实例
2019/06/17 Javascript
微信小程序实现订单倒计时
2020/11/01 Javascript
layui将table转化表单显示的方法(即table.render转为表单展示)
2019/09/24 Javascript
ES6实现图片切换特效代码
2020/01/14 Javascript
python编写暴力破解FTP密码小工具
2014/11/19 Python
python同时给两个收件人发送邮件的方法
2015/04/30 Python
Flask框架请求钩子与request请求对象用法实例分析
2019/11/07 Python
keras模型保存为tensorflow的二进制模型方式
2020/05/25 Python
HTML5实现表单自动验证功能实例代码
2017/01/11 HTML / CSS
中科方德软件测试面试题
2016/04/21 面试题
对象的序列化(serialization)类是面向流的,应如何将对象写入到随机存取文件中
2015/06/22 面试题
编辑找工作求职信分享
2014/01/03 职场文书
法学个人求职信范文
2014/01/27 职场文书
高一化学教学反思
2014/02/05 职场文书
党员对照检查材料思想汇报(党的群众路线)
2014/09/24 职场文书
2014年单位法制宣传日活动总结
2014/11/01 职场文书
英文邀请函
2015/02/02 职场文书
清洁工个人工作总结
2015/03/05 职场文书
2015年勤工助学工作总结
2015/04/29 职场文书
公司周年庆典致辞
2015/07/30 职场文书
少先队中队工作总结
2015/08/14 职场文书
2016年小学“感恩教师”主题队日活动总结
2016/04/01 职场文书
python设置 matplotlib 正确显示中文的四种方式
2021/05/10 Python