Python性能分析工具

以下主要介绍cProfile和line_profiler两个耗时分析工具。两种工具结合使用,充分认识自己的代码。

cProfile-函数调用耗时分析工具

cProfile是Python内置的工具,使用C语言编写,时间开销较少。使用方法如下例:

import cProfile


def test():
    print("hello world")

# 直接把分析结果打印到控制台
cProfile.run("test()")
# 把分析结果保存到result.out文件中
cProfile.run("test()", filename="result.out")
# 增加排序方式(建议使用该方法)
cProfile.run("test()", filename = None, sort="cumulative")

  tip:保存的分析文件并不能通过记事本直接显示,需要使用pstats分析工具。

其输出结果如下格式:

        2312262 function calls (2282114 primitive calls) in 9.583 seconds

Ordered by: cumulative time

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
    60    0.335    0.006    9.467    0.158 index.py:19(main)  
    55    0.348    0.006    2.030    0.037 imgproc.py:182(func1)
    232    0.099    0.000    1.799    0.008 imgproc.py:130(func2)
    512    1.652    0.003    1.652    0.003 {func3}     

每一列的含义为:

  • ncalls:函数调用的次数。
  • tottime:函数总运行时间,不含函数中子函数的时间。
  • percall:函数的平均耗时,= tottime/ncalls。
  • cumtime:函数包含所有子函数的总运行时间。
  • percall:函数的平均耗时,= cumtime/ncalls。
  • filename:lineno(function):函数具体信息。

line_profiler-代码行耗时分析工具

仅仅使用cProfile定位耗时函数往往是不够的,我们还需要这些函数的每行代码进行耗时分析,定位到具体耗时代码。这时就需要使用line_profilter工具。

该工具库非Python内置,需要提前安装line_profilter包。

  tip:截止到2021年,直接从pypl下载安装会报错,这里提供一下链接,请根据自己的使用环境下载安装。

使用方法如下例:

import line_profiler
import sys


def test():
    print("hello world")

prof = line_profiler.LineProfiler(test)
prof.enable()  # 开始性能分析
test()
prof.disable()  # 停止性能分析
prof.print_stats(sys.stdout)

由于我们更多情况下,是对子函数进行分析,因此下面介绍其命令行工具,以实现该目的。其代码实例如下,需要注意的是我们并不需要import任意库,只需要对待分析函数添加装饰器@profile,并在代码中运行该函数或其上层函数。

@profile
def test():
    print("hello world")


def main():
    test()


if __name__ == "__main__" :
    main()

该代码文件并不能直接使用python解释器直接运行,很显然因为我们并未import该装饰器。此时我们需要在命令行工具中执行如下命令,便会在所有代码执行完毕后显示函数的分析结果:

PS C:\Users\xzhang>kernprof -l -v test.py
Wrote profile results to test.py.lprof
Timer unit: 1e-07 s

Total time: 0.0020232 s
File: test.py
Function: test at line 296

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
   296                                           @profile
   297                                           def test():
   298         1       2303.0   2303.0     11.4      img = np.zeros((1000, 1000), dtype=np.uint8)      
   299         1        571.0    571.0      2.8      cv2.circle(img, (500, 500), 100, 255, -1, lineType=cv2.LINE_AA)
   300         1      16505.0  16505.0     81.6      np_out = np.count_nonzero(img)
   301         1        853.0    853.0      4.2      cv_out = cv2.countNonZero(img)

命令行代码最后一个参数为该代码所属.py的相对路径,同时运行结束后会在代码文件同级生成一个.lprof文件。其输出如上格式。每一列的含义为:

  • Line: 该行代码行号
  • Hits: 该行代码运行次数
  • Time: 该行代码运行总时间
  • Time Per Hit: 该行代码运行平均耗时,= Time/Hits
  • Line Contents: 该行代码内容

因此针对我们视觉算法耗时优化的一般流程为:首先使用cProfile对所有函数进行耗时统计,找到其中耗时严重的函数,再使用line_profiler对该段代码逐行进行耗时分析,找到其中耗时严重的代码进行重构或者参数调整。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值