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编写爬虫小程序
May 14 Python
python实现rsa加密实例详解
Jul 19 Python
Python实现读取TXT文件数据并存进内置数据库SQLite3的方法
Aug 08 Python
Python3处理HTTP请求的实例
May 10 Python
解决python3 Pycharm上连接数据库时报错的问题
Dec 03 Python
详解Python with/as使用说明
Dec 13 Python
python爬虫租房信息在地图上显示的方法
May 13 Python
详解python实现交叉验证法与留出法
Jul 11 Python
Pytorch 实现权重初始化
Dec 31 Python
python中如何使用insert函数
Jan 09 Python
如何使用pycharm连接Databricks的步骤详解
Sep 23 Python
python collections模块的使用
Oct 16 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
腾讯QQ php程序员面试题目整理
2010/06/08 PHP
PHP 获取文件路径(灵活应用__FILE__)
2013/02/15 PHP
PHP操作Memcache实例介绍
2013/06/14 PHP
ThinkPHP模板中数组循环实例
2014/10/30 PHP
PHP实现链式操作的原理详解
2016/09/16 PHP
php实现生成PDF文件的方法示例【基于FPDF类库】
2018/07/21 PHP
textarea的value是html文件源代码,存成html文件的代码
2007/04/20 Javascript
对象特征检测法判断浏览器对javascript对象的支持
2009/07/25 Javascript
理清apply(),call()的区别和关系
2011/08/14 Javascript
javascript实用小函数使用介绍
2013/11/11 Javascript
javascript框架设计之框架分类及主要功能
2015/06/23 Javascript
JavaScript截取、切割字符串的技巧
2016/01/07 Javascript
漂亮实用的页面loading(加载)封装代码
2017/02/03 Javascript
微信小程序登录态控制深入分析
2017/04/12 Javascript
vue.js获取数据库数据实例代码
2017/05/26 Javascript
基于angular6.0实现的一个组件懒加载功能示例
2018/04/12 Javascript
js计算最大公约数和最小公倍数代码实例
2019/09/11 Javascript
[04:16]DOTA2英雄梦之声_第09期_斧王
2014/06/21 DOTA
[46:55]完美世界DOTA2联赛决赛 FTD vs Phoenix 第三场 11.08
2020/11/11 DOTA
浅析python 中__name__ = '__main__' 的作用
2014/07/05 Python
python使用mysql的两种使用方式
2018/03/07 Python
使用Python给头像戴上圣诞帽的图像操作过程解析
2019/09/20 Python
tensorflow的ckpt及pb模型持久化方式及转化详解
2020/02/12 Python
python3+openCV 获取图片中文本区域的最小外接矩形实例
2020/06/02 Python
Python单元测试及unittest框架用法实例解析
2020/07/09 Python
calendar在python3时间中常用函数举例详解
2020/11/18 Python
css背景图片的背景裁切、背景透明度、背景变换等效果运用
2012/12/24 HTML / CSS
AmazeUI 加载进度条的实现示例
2020/08/20 HTML / CSS
大学毕业生最详细的自我评价分享
2013/11/18 职场文书
企业办公室主任岗位职责
2014/02/19 职场文书
党员2014两会学习心得体会
2014/03/17 职场文书
民政局副局长民主生活会个人整改措施
2014/10/04 职场文书
巾帼文明岗事迹材料
2014/12/24 职场文书
报案材料怎么写
2015/05/25 职场文书
企业团队精神心得体会
2016/01/19 职场文书
SQL Server代理:理解SQL代理错误日志处理方法
2021/06/30 SQL Server