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中的对象拷贝示例 python引用传递
Jan 23 Python
C#返回当前系统所有可用驱动器符号的方法
Apr 18 Python
Python中用PIL库批量给图片加上序号的教程
May 06 Python
python中getaddrinfo()基本用法实例分析
Jun 28 Python
使用python 爬虫抓站的一些技巧总结
Jan 10 Python
解决python3 requests headers参数不能有中文的问题
Aug 21 Python
python matplotlib饼状图参数及用法解析
Nov 04 Python
基于YUV 数据格式详解及python实现方式
Dec 09 Python
python模拟斗地主发牌
Apr 22 Python
Python flask框架端口失效解决方案
Jun 04 Python
基于K.image_data_format() == 'channels_first' 的理解
Jun 29 Python
如何基于Python Matplotlib实现网格动画
Jul 20 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中突破基于HTTP_REFERER的防盗链措施(stream_context_create)
2011/03/29 PHP
php学习之流程控制实现代码
2011/06/09 PHP
php实现留言板功能(会话控制)
2017/05/23 PHP
PHP实现的各类hash算法长度及性能测试实例
2017/08/27 PHP
基于jquery实现的可以编辑选择的下拉框的代码
2010/11/19 Javascript
javascript suggest效果 自动完成实现代码分享
2012/02/17 Javascript
jQuery实现长文字部分显示代码
2013/05/13 Javascript
解决Jquery鼠标经过不停滑动的问题
2014/03/03 Javascript
Jquery对数组的操作技巧整理
2014/03/25 Javascript
javascript框架设计读书笔记之数组的扩展与修复
2014/12/02 Javascript
JavaScript中遍历对象的property的3种方法介绍
2014/12/30 Javascript
跟我学习javascript的call(),apply(),bind()与回调
2015/11/16 Javascript
JavaScript的Ext JS框架中的GridPanel组件使用指南
2016/05/21 Javascript
Angular 路由route实例代码
2016/07/12 Javascript
实现点击下箭头变上箭头来回切换的两种方法【推荐】
2016/12/14 Javascript
Bootstrap 模态框实例插件案例分析
2016/12/28 Javascript
Vue 2.5 Level E 发布了: 新功能特性一览
2017/10/24 Javascript
Vue+Express实现登录状态权限验证的示例代码
2019/05/05 Javascript
使用express来代理服务的方法
2019/06/21 Javascript
JAVA面试题 static关键字详解
2019/07/16 Javascript
vue+django实现一对一聊天功能的实例代码
2019/07/17 Javascript
[00:13]天涯墨客二技能展示
2018/08/25 DOTA
[31:55]完美世界DOTA2联赛循环赛 IO vs GXR BO2第一场 11.04
2020/11/05 DOTA
python中的闭包函数
2018/02/09 Python
Atom的python插件和常用插件说明
2018/07/08 Python
pycharm运行和调试不显示结果的解决方法
2018/11/30 Python
8段用于数据清洗Python代码(小结)
2019/10/31 Python
django formset实现数据表的批量操作的示例代码
2019/12/06 Python
印度尼西亚在线时尚购物网站:ZALORA印尼
2016/08/02 全球购物
艺术用品:Arteza
2018/11/25 全球购物
家具厂厂长岗位职责
2014/01/01 职场文书
2014最新版群众路线四风整改措施
2014/09/24 职场文书
个人四风对照检查材料
2014/09/26 职场文书
应届生求职自荐信范文
2015/03/04 职场文书
爱国主义教育主题班会
2015/08/13 职场文书
2016年教师党员创先争优承诺书
2016/03/24 职场文书