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中解析JSON并同时进行自定义编码处理实例
Feb 08 Python
numpy中实现ndarray数组返回符合特定条件的索引方法
Apr 17 Python
完美解决python中ndarray 默认用科学计数法显示的问题
Jul 14 Python
Selenium元素的常用操作方法分析
Aug 10 Python
将string类型的数据类型转换为spark rdd时报错的解决方法
Feb 18 Python
详解Python装饰器
Mar 25 Python
python3反转字符串的3种方法(小结)
Nov 07 Python
详解python内置常用高阶函数(列出了5个常用的)
Feb 21 Python
Python datetime模块使用方法小结
Jun 18 Python
如何教少儿学习Python编程
Jul 10 Python
pytorch Dataset,DataLoader产生自定义的训练数据案例
Mar 03 Python
Python中第三方库Faker的使用详解
Apr 02 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数组函数array_key_exists()小结
2015/12/10 PHP
解读PHP中上传文件的处理问题
2016/05/29 PHP
简单谈谈PHP中的trait
2017/02/25 PHP
javascript 文档的编码问题解决
2009/03/01 Javascript
jcrop基本参数一览
2013/07/16 Javascript
处理文本部分内容的TextRange对象应用实例
2014/07/29 Javascript
jquery实现的横向二级导航效果代码
2015/08/26 Javascript
JS实现超简单的仿QQ折叠菜单效果
2015/09/21 Javascript
javascript实现的网站访问量统计代码
2015/12/20 Javascript
深入理解JavaScript中的call、apply、bind方法的区别
2016/05/30 Javascript
js实现打地鼠小游戏
2017/02/13 Javascript
JavaScript创建对象的七种方式(推荐)
2017/06/26 Javascript
vue2实现可复用的轮播图carousel组件详解
2017/11/27 Javascript
详解Node.js中的Async和Await函数
2018/02/22 Javascript
vue实现a标签点击高亮方法
2018/03/17 Javascript
Vue项目从webpack3.x升级webpack4不完全指南
2019/04/28 Javascript
layui的select联动实现代码
2019/09/28 Javascript
微信小程序一周时间表功能实现
2019/10/17 Javascript
python matlibplot绘制3D图形
2018/07/02 Python
Python with关键字,上下文管理器,@contextmanager文件操作示例
2019/10/17 Python
python模块常用用法实例详解
2019/10/17 Python
Python之Class&amp;Object用法详解
2019/12/25 Python
Python使用sqlite3模块内置数据库
2020/05/07 Python
Python collections.defaultdict模块用法详解
2020/06/18 Python
python计算auc的方法
2020/09/09 Python
JSF如何进行表格处理及取值
2012/08/06 面试题
办公室前台岗位职责范本
2013/12/10 职场文书
大学生职业规划论文
2014/01/11 职场文书
应届生自荐信范文
2014/02/21 职场文书
医学生临床实习自我评价
2014/03/07 职场文书
竞选宣传委员演讲稿
2014/05/24 职场文书
法人委托书范本
2014/09/15 职场文书
会议欢迎词
2015/01/23 职场文书
python开发飞机大战游戏
2021/07/15 Python
《艾尔登法环》Boss腐烂树灵很有可能是《黑暗之魂3》的一个废案
2022/04/11 其他游戏
Java结构型设计模式之组合模式详解
2022/09/23 Java/Android