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 相关文章推荐
关于反爬虫的一些简单总结
Dec 13 Python
python决策树之CART分类回归树详解
Dec 20 Python
python的staticmethod与classmethod实现实例代码
Feb 11 Python
python3调用R的示例代码
Feb 23 Python
pycharm恢复默认设置或者是替换pycharm的解释器实例
Oct 29 Python
用python 实现在不确定行数情况下多行输入方法
Jan 28 Python
Python numpy中矩阵的基本用法汇总
Feb 12 Python
Python Request爬取seo.chinaz.com百度权重网站的查询结果过程解析
Aug 13 Python
python打包成so文件过程解析
Sep 28 Python
python OpenCV GrabCut使用实例解析
Nov 11 Python
Python StringIO及BytesIO包使用方法解析
Jun 15 Python
Python pickle模块常用方法代码实例
Oct 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+mysql 采用ajax技术的 省 市 地 3级联动无刷新菜单 源码
2006/12/16 PHP
给apache2.2加上mod_encoding模块後 php5.2.0 处理url出现bug
2007/04/12 PHP
php dirname(__FILE__) 获取当前文件的绝对路径
2011/06/28 PHP
PHP CLI模式下的多进程应用分析
2013/06/03 PHP
php中get_meta_tags()、CURL与user-agent用法分析
2014/12/16 PHP
THINKPHP支持YAML配置文件的设置方法
2015/03/17 PHP
PHP自定义函数实现数组比较功能示例
2017/10/19 PHP
js loading加载效果实现代码
2009/11/24 Javascript
Jquery实现鼠标移上弹出提示框、移出消失思路及代码
2013/05/19 Javascript
javascript实现焦点滚动图效果 具体方法
2013/06/24 Javascript
js数组方法扩展实现数组统计函数
2014/04/09 Javascript
利用javascript实现的三种图片放大镜效果实例(附源码)
2017/01/23 Javascript
过滤器vue.filters的使用方法实现
2019/09/18 Javascript
vue远程加载sfc组件思路详解
2019/12/25 Javascript
[57:41]Secret vs Serenity 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
Python中使用Inotify监控文件实例
2015/02/14 Python
Python处理菜单消息操作示例【基于win32ui模块】
2018/05/09 Python
Python实现矩阵相乘的三种方法小结
2018/07/26 Python
Python 中PyQt5 点击主窗口弹出另一个窗口的实现方法
2019/07/04 Python
Python 矩阵转置的几种方法小结
2019/12/02 Python
python如何把字符串类型list转换成list
2020/02/18 Python
python生成并处理uuid的实现方式
2020/03/03 Python
python实现视频压缩功能
2020/12/18 Python
白色公司:The White Company
2017/10/11 全球购物
为有想象力的人提供的生活方式商店:Firebox
2018/06/04 全球购物
Hunter Boots美国官方网站:赫特威灵顿雨靴
2018/06/16 全球购物
Tea Collection官网:一家位于旧金山的童装公司
2020/08/07 全球购物
十月份红领巾广播稿
2014/01/22 职场文书
简历自我评价模版
2014/01/31 职场文书
安全标语大全
2014/06/10 职场文书
今日说法观后感
2015/06/08 职场文书
节水宣传标语口号
2015/12/26 职场文书
《平移和旋转》教学反思
2016/02/19 职场文书
《槐乡的孩子》教学反思
2016/02/20 职场文书
检讨书范文
2019/04/16 职场文书
Golang二维切片初始化的实现
2021/04/08 Golang