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类方法__init__和__del__构造、析构过程分析
Mar 06 Python
django接入新浪微博OAuth的方法
Jun 29 Python
python实现下载文件的三种方法
Feb 09 Python
Python 遍历列表里面序号和值的方法(三种)
Feb 17 Python
python分割列表(list)的方法示例
May 07 Python
Python 通过URL打开图片实例详解
Jun 01 Python
pip安装时ReadTimeoutError的解决方法
Jun 12 Python
解决项目pycharm能运行,在终端却无法运行的问题
Jan 19 Python
33个Python爬虫项目实战(推荐)
Jul 08 Python
Python实现K折交叉验证法的方法步骤
Jul 11 Python
python 牛顿法实现逻辑回归(Logistic Regression)
Oct 15 Python
pycharm + django跨域无提示的解决方法
Dec 06 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实现小型站点广告管理
2006/10/09 PHP
PHP的pcntl多进程用法实例
2015/03/19 PHP
微信接口生成带参数的二维码
2017/07/31 PHP
浅谈Javascript嵌套函数及闭包
2010/11/09 Javascript
Array, Array Constructor, for in loop, typeof, instanceOf
2011/09/13 Javascript
jquery如何改变html标签的样式(两种实现方法)
2013/01/16 Javascript
html+css+js实现xp window界面及有关功能
2013/03/26 Javascript
javasctipt如何显示几分钟前、几天前等
2014/04/30 Javascript
浅谈NodeJS中require路径问题
2015/05/07 NodeJs
AngularJs directive详解及示例代码
2016/09/01 Javascript
JS禁止查看网页源代码的实现方法
2016/10/12 Javascript
AngularJS双向绑定和依赖反转实例详解
2017/04/15 Javascript
微信小程序自定义模态对话框实例详解
2017/08/16 Javascript
layui 实现表单和文件上传一起传到后台的例子
2019/09/16 Javascript
vue实现文件上传读取及下载功能
2020/11/17 Javascript
python多线程http下载实现示例
2013/12/30 Python
Python的高级Git库 Gittle
2014/09/22 Python
Zookeeper接口kazoo实例解析
2018/01/22 Python
python 通过xml获取测试节点和属性的实例
2018/03/31 Python
Python爬虫实现(伪)球迷速成
2018/06/10 Python
Python 实现自动导入缺失的库
2019/10/29 Python
IronPython连接MySQL的方法步骤
2019/12/27 Python
matlab灰度图像调整及imadjust函数的用法详解
2020/02/27 Python
python实现猜拳游戏项目
2020/11/30 Python
牵手50香港:专为黄金岁月的单身人士而设的交友网站
2020/08/14 全球购物
腾讯公司的一个sql题
2013/01/22 面试题
临床专业自荐信
2014/06/22 职场文书
拆迁委托协议书
2014/09/15 职场文书
毕业实习证明(4篇)
2014/10/28 职场文书
起诉离婚协议书样本
2014/11/25 职场文书
农业项目投资意向书
2015/05/09 职场文书
撤诉申请书法院范本
2015/05/18 职场文书
创业计划书之香辣虾火锅
2019/09/23 职场文书
一文搞懂python异常处理、模块与包
2021/06/26 Python
Z-Order加速Hudi大规模数据集方案分析
2022/03/31 Servers
Spring Data JPA框架Repository自定义实现
2022/04/28 Java/Android