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和GO语言实现的消息摘要算法示例
Mar 10 Python
Python日志模块logging基本用法分析
Aug 23 Python
BP神经网络原理及Python实现代码
Dec 18 Python
python numpy 按行归一化的实例
Jan 21 Python
python使用pandas处理excel文件转为csv文件的方法示例
Jul 18 Python
django 信号调度机制详解
Jul 19 Python
Python turtle绘画象棋棋盘
Aug 21 Python
python sorted函数的小练习及解答
Sep 18 Python
Python完全识别验证码自动登录实例详解
Nov 24 Python
Python 使用threading+Queue实现线程池示例
Dec 21 Python
Django操作session 的方法
Mar 09 Python
Python批量将csv文件转化成xml文件的实例
May 10 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 &amp;&amp; 逻辑与运算符使用说明
2010/03/04 PHP
了解PHP的返回引用和局部静态变量
2015/06/04 PHP
jQuery插件multiScroll实现全屏鼠标滚动切换页面特效
2015/04/12 Javascript
JS实现横向与竖向两个选项卡Tab联动的方法
2015/09/27 Javascript
Jquery uploadify上传插件使用详解
2016/01/13 Javascript
基于touch.js手势库+zepto.js插件开发图片查看器(滑动、缩放、双击缩放)
2016/11/17 Javascript
jquery UI Datepicker时间控件冲突问题解决
2016/12/16 Javascript
angularJS深拷贝详解
2017/03/23 Javascript
[45:16]完美世界DOTA2联赛PWL S3 Magma vs Phoenix 第一场 12.12
2020/12/16 DOTA
35个Python编程小技巧
2014/04/01 Python
python执行子进程实现进程间通信的方法
2015/06/02 Python
Python自定义线程池实现方法分析
2018/02/07 Python
Linux下python3.7.0安装教程
2018/07/30 Python
Python使用修饰器进行异常日志记录操作示例
2019/03/19 Python
Python代码太长换行的实现
2019/07/05 Python
python3模拟实现xshell远程执行liunx命令的方法
2019/07/12 Python
Python 等分切分数据及规则命名的实例代码
2019/08/16 Python
Python换行与不换行的输出实例
2020/02/19 Python
Python实现检测文件的MD5值来查找重复文件案例
2020/03/12 Python
详解django使用include无法跳转的解决方法
2020/03/19 Python
Python多进程multiprocessing、进程池用法实例分析
2020/03/24 Python
8款使用 CSS3 实现超炫的 Loading(加载)的动画效果
2015/03/17 HTML / CSS
Shopee菲律宾:在线购买和出售
2019/11/25 全球购物
"引用"与多态的关系
2013/02/01 面试题
如何删除一个表里面的重复行
2013/07/13 面试题
工程部主管岗位职责
2013/11/17 职场文书
校长岗位职责
2013/11/26 职场文书
建筑专业毕业生自荐信
2014/05/25 职场文书
会计学专业自荐信
2014/06/25 职场文书
献爱心大型公益活动策划方案
2014/09/15 职场文书
内勤岗位职责范本
2015/04/13 职场文书
2015年学校禁毒工作总结
2015/05/27 职场文书
python基础入门之普通操作与函数(三)
2021/06/13 Python
小程序实现文字循环滚动动画
2021/06/14 Javascript
Nginx配置文件详解以及优化建议指南
2021/09/15 Servers