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登录pop3邮件服务器接收邮件的方法
Apr 30 Python
深入解析Python中的lambda表达式的用法
Aug 28 Python
Python迭代和迭代器详解
Nov 10 Python
python机器学习理论与实战(四)逻辑回归
Jan 19 Python
基于anaconda下强大的conda命令介绍
Jun 11 Python
Python爬虫小技巧之伪造随机的User-Agent
Sep 13 Python
python使用pdfminer解析pdf文件的方法示例
Dec 20 Python
利用python实现简易版的贪吃蛇游戏(面向python小白)
Dec 30 Python
Python实战购物车项目的实现参考
Feb 20 Python
使用python脚本自动创建pip.ini配置文件代码实例
Sep 20 Python
Python生成器实现简单&quot;生产者消费者&quot;模型代码实例
Mar 27 Python
分享3个非常实用的 Python 模块
Mar 03 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中header和session_start前不能有输出原因分析
2013/01/11 PHP
php读取纯真ip数据库使用示例
2014/01/26 PHP
php获取参数的几种方法总结
2014/02/18 PHP
Thinkphp无限级分类代码
2015/11/11 PHP
PHP编程实现计算抽奖概率算法完整实例
2017/08/09 PHP
解决Extjs4中form表单提交后无法进入success函数问题
2013/11/26 Javascript
JS短路原理的应用示例 精简代码的途径
2013/12/13 Javascript
js实现简单随机抽奖的方法
2015/01/27 Javascript
JS实现两表格里数据来回转移的方法
2015/05/28 Javascript
javascript中的正则表达式使用详解
2015/08/30 Javascript
Ionic如何创建APP项目
2016/06/03 Javascript
AngularJS创建自定义指令的方法详解
2016/11/03 Javascript
VUE实现表单元素双向绑定(总结)
2017/08/08 Javascript
JavaScript正则表达式和级联效果
2017/09/14 Javascript
解决vuejs项目里css引用背景图片不能显示的问题
2018/09/13 Javascript
axios+Vue实现上传文件显示进度功能
2019/04/14 Javascript
Python中标准模块importlib详解
2017/04/16 Python
Python实现读取并保存文件的类
2017/05/11 Python
Python实现图片滑动式验证识别方法
2017/11/09 Python
Python sklearn KFold 生成交叉验证数据集的方法
2018/12/11 Python
使用Python计算玩彩票赢钱概率
2019/06/26 Python
python 用户交互输入input的4种用法详解
2019/09/24 Python
详解用Pytest+Allure生成漂亮的HTML图形化测试报告
2020/03/31 Python
用python绘制樱花树
2020/10/09 Python
jupyter notebook快速入门及使用详解
2020/11/13 Python
Mixbook加拿大:照片书,照片卡,剪贴簿,年历和日历
2017/02/21 全球购物
Hudson Jeans官网:高级精制牛仔裤
2018/11/28 全球购物
J2SDK1.5与J2SDK5.0有什么区别
2012/09/19 面试题
审核会计岗位职责
2013/11/08 职场文书
高中军训广播稿
2014/01/14 职场文书
法律专业学生的自我评价
2014/02/07 职场文书
教师职称自我鉴定
2014/02/12 职场文书
入学申请自荐信范文
2014/02/26 职场文书
活动总结怎么写啊
2014/05/07 职场文书
音乐剧猫观后感
2015/06/04 职场文书
python基础之类方法和静态方法
2021/10/24 Python