文章目录

  • 引言
  • 1. cProfile:最便捷的性能分析
    • 保存性能数据
    • 查看性能数据
    • 查看耗时最多的子函数
    • 查看特定名称函数的耗时
  • 2. timeit:计算小代码片段的耗时
  • 3. IDE中的性能分析
  • 小结

引言

如果你想优化python程序的运行效率,你会从哪里下手?

首先,我们要找到「性能瓶颈」,比如哪些函数的运行效率低、计算时间长,然后分析原因,针对性地进行优化。

最朴素的方法是,在你预估的函数前后加上time.perf_counter()1,然后得出这个函数的运行时间。但这种方法不适用于具有大量函数调用的程序。

import timestart = time.perf_counter()
func()
print("cost %s second" % (time.perf_counter() - start))

python有很多性能分析工具,功能强大,可以帮助我们对各种函数的性能进行分析。

这篇文章就介绍三种简单的性能分析工具。其中cProfile和timeit都是python标准库中的工具,无需安装第三方库,看完本篇文章,教你快速上手。

1. cProfile:最便捷的性能分析

推荐指数: ⭐️⭐️⭐️⭐️

cProfile是python标准库中一个使用便捷、开销合理的 C 扩展,适用于分析长时间运行的程序。2

不想阅读太多细节的小伙伴,可以直接看代码,非常简单,直接在cProfile.run中输入目标函数名称:

import cProfile
import test_modulecProfile.run('test_module.func()')

在程序运行完后,就会在控制台打印test_module.func()运行的具体耗时情况:

538569 function calls (519249 primitive calls) in 71.446 secondsOrdered by: standard namencalls  tottime  percall  cumtime  percall filename:lineno(function)44    0.002    0.000    0.197    0.004 ImageFile.py:154(load)18    0.000    0.000    0.001    0.000 ImageFile.py:278(load_prepare)1    0.000    0.000    0.000    0.000 ImageFile.py:30(<module>)1    0.000    0.000    0.000    0.000 ImageFile.py:313(StubImageFile)1    0.000    0.000    0.000    0.000 ImageFile.py:339(Parser)13    0.001    0.000    1.348    0.104 ImageFile.py:478(_save)

每一行依次列出了各个子函数的运行分析信息:

  • ncalls
    调用次数

  • tottime
    在给定函数中花费的总时间(不包括调用子函数的时间

  • percall
    tottime除以ncalls的商

  • cumtime
    是在这个函数和所有子函数中花费的累积时间(从调用到退出)

  • percall
    是cumtime除以原始调用次数的商

  • filename:lineno(function)
    提供每个函数的各自信息

保存性能数据

如果你想保存这些性能数据,在run函数的参数中加上’restats’文件名:

cProfile.run('main()','restats')

就会保存到当前目录下的restats文件中。

查看性能数据

加载这些数据,可以进行后续的比较分析。

import pstats
from pstats import SortKey# 加载保存到restats文件中的性能数据
p = pstats.Stats('restats')# 打印所有统计信息
p.strip_dirs().sort_stats(-1).print_stats()

查看耗时最多的子函数

最常用的是,查看耗时最多的函数排序,比如前十个:

# 打印累计耗时最多的10个函数
p.sort_stats(SortKey.CUMULATIVE).print_stats(10)# 打印内部耗时最多的10个函数(不包含子函数)
p.sort_stats(SortKey.TIME).print_stats(10)


上面两个例子分别用到用SortKey.CUMULATIVESortKey.TIME参数。

SortKey的具体参数如下表所示3

查看特定名称函数的耗时

例如,我们在耗时排序中,发现一些加载函数的耗时较大,可以单独统计下包含load的调用信息:

# 打印包含load的函数名的调用者统计信息
p.print_callers(.5, 'load')

0.5表示列表被剔除到其原始大小的50%,然后保留包含load的行:

例如,还可以查看哪些类的初始化__init__函数耗时较多:

# 按耗时排序,依次打印类的__init__方法的统计信息
p.sort_stats(SortKey.CUMULATIVE).print_stats('__init__')

2. timeit:计算小代码片段的耗时

推荐指数: ⭐️⭐️

timeit适用于测量小段代码的耗时,可以在python代码中调用,也可以在命令行中调用4。timeit的设计避免了许多用于测量执行时间的常见陷阱。

测试你写的函数的运行时间:

def test():"""Stupid test function"""L = [i for i in range(100)]if __name__ == '__main__':import timeitprint(timeit.timeit("test()", setup="from __main__ import test"))

测试一个语句的运行时间:

$ python -m timeit 'if hasattr(str, "__bool__"): pass'
50000 loops, best of 5: 4.26 usec per loop

使用方式:
python -m timeit [-n N] [-r N] [-u U] [-s S] [-h] [statement ...]

  • -n N, --number=N
    执行“语句”多少次

  • -r N, --repeat=N
    重复计时器多少次(默认 5)

  • -s S, --setup=S
    最初执行一次的语句(默认pass)

  • -p, --process
    测量进程时间,而不是挂钟时间,使用time.process_time() 代替time.perf_counter(),这是默认值
    3.3 版中的新功能。

  • -u, --unit=U
    指定定时器输出的时间单位;可以选择 nsec、usec、msec 或 sec
    3.5 版中的新功能。

  • -v, --verbose
    打印原始计时结果;重复以获得更多数字精度

  • -h, --help
    打印一个简短的使用信息并退出

3. IDE中的性能分析

推荐指数: ⭐️⭐️⭐️

如果你有IDE,那么很多IDE都提供了性能分析的相关工具。

以pycharm 专业版为例,从Run中点击Profile,即可对当前python脚本进行性能分析。


程序运行结束后,pycharm会生成以下统计:

这里列出了子函数的名称、调用次数、耗时等信息,双击函数名可以查看对应源码。

小结

本文整理了三个常用的python性能分析工具,帮助你定位python程序的性能瓶颈。

如果对你有所帮助,欢迎一键三连,支持下博主。


  1. https://docs.python.org/3/library/time.html#time.perf_counter ↩︎

  2. https://docs.python.org/3/library/profile.html ↩︎

  3. https://docs.python.org/3/library/profile.html#module-pstats ↩︎

  4. https://docs.python.org/3/library/timeit.html ↩︎

教你3个python「性能分析」工具,再也不用自己计算函数耗时了相关推荐

  1. python脚本性能分析

    在进行python开发时需要对python脚本的性能分析,以便对python脚本进行优化,下面使用cProfile和 pstats对python脚本性能分析. cProfile思路 1.使用cProf ...

  2. Linux性能分析命令工具汇总

    转自:http://rdc.hundsun.com/portal/article/731.html?ref=myread 出于对Linux操作系统的兴趣,以及对底层知识的强烈欲望,因此整理了这篇文章. ...

  3. 阿拉丁统计 2.0丨筛选?分组?聚合能力?「高级分析」精细化数据统计管理

    前两期,我们分享了阿拉丁统计 2.0 的「开源 SDK」和「指标商店」,后台收到了很多粉丝的咨询与试用申请.本期我们就从"事件分析"着手,开启第三个话题--「高级分析」. 在日常工 ...

  4. B 站 18 岁高中生火了:历时 200 天,成功造了个机器人!Python「注入灵魂」

    来自新智元 [导读]十八岁的你在做什么?凌十七,18 岁,耗时 200 天,用树莓派 DIY 机器人.这位 B 站 up 主爆火出圈,纯手工自制塑料外壳,焊接钢架,250 行 Python 代码为其「 ...

  5. python黑科技脚本_利用Python实现FGO自动战斗脚本,再也不用爆肝啦~

    欢迎点击右上角关注小编,除了分享技术文章之外还有很多福利,私信学习资料可以领取包括不限于Python实战演练.PDF电子文档.面试集锦.学习资料等. 利用Python实现FGO自动战斗脚本,再也不用爆 ...

  6. python实现抢劵_用Python实现微信自动化抢红包,再也不用担心抢不到红包了

    1. 概述 刚刚收到了两个消息,一个好消息,一个坏消息. 先说好消息,好消息就是微信群里有人要发红包,开心~ 不过转念一想,前几次的红包一个都没抢到,这次???不由自主的叹了一口气 ... 过了一会, ...

  7. python清理垃圾_用Python自动清理系统垃圾,再也不用360安全卫士了

    用Python自动清理系统垃圾,再也不用360安全卫士了 在Windows在安装和使用过程中都会产生相当多的垃圾文件,包括临时文件(如:.tmp.._mp)日志文件(.log).临时帮助文件(.gid ...

  8. 【ZT】iSpring Free Cam – 免费易用的「录制屏幕」工具 [Windows]

    http://subscribe.mail.10086.cn/subscribe/readAll.do?columnId=280&itemId=6101839 iSpring Free Cam ...

  9. Python快速计算函数耗时timeit

    文章目录 问题描述 解决方案 魔法命令 `%%timeit` timeit 模块 参考文献 问题描述 Python 快速计算函数耗时 import timedef f():time.sleep(2) ...

最新文章

  1. 我理解的接口测试(一)
  2. SUSE Linux SFTP服务器配置
  3. Theano2.1.1-基础知识之准备工作
  4. 口的内存映射 stm32f7_STM32F7高速缓存
  5. hadoop2.6.5安装文档及解决root用户无法ssh localhost的问题
  6. java快速教程_Java快速入门
  7. 集成开放平台标准化连接器之基于OAS3.0的API管理能力
  8. Hello Blazor:(8)启用深色模式
  9. (二十四)【2021 ACL】OntoED: Low-resource Event Detection with Ontology Embedding
  10. 如何下载Lucene.net源码
  11. 搭建一个企业级的Vue工程!
  12. 淘宝网物流宝平台11日上线 全面开放API接口
  13. 按指定字符分割字符串
  14. 让油猴脚本只执行一次
  15. 机器学习读书笔记之决策树
  16. 手机网页版JS压缩上传图片--base64位 兼容IOS和安卓
  17. xv6进程切换-swtch函数
  18. Unity --- 角色动画的使用以及按键控制角色运动
  19. 尝试投了下 OR 被拒,领教了顶级期刊的审稿
  20. maya为什么不能导出fbx_maya的模型导出为OBJ,然后导入到3dmax后uv全乱了 (导出FBX更不行,导出的FBX文件放max里面基本没面了)...

热门文章

  1. Robotium 数据驱动测试框架
  2. 张开双臂迎接“云时代“的到来
  3. 面试:对象的生命周期
  4. Web前端 HTML 优化启动性能
  5. Docker 使用 docker push 命令 推送本地镜像到远程DockerHub仓库服务器
  6. ubuntu14.04修改limits.conf后链接限制仍然不生效
  7. MySQL故障检测_mysql主从故障检测处理脚本
  8. Jenkins之Log Parse的使用
  9. 【React 基础】之 React 面向组件编程
  10. C#LeetCode刷题之#169-求众数(Majority Element)