鱼C论坛

 找回密码
 立即注册
查看: 2397|回复: 2

[技术交流] Python 小技巧 045:性能分析(二)—— line_profiler

[复制链接]
发表于 2020-1-1 15:14:07 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 zltzlt 于 2020-1-1 15:21 编辑

Python 性能分析器 —— line_profiler


line_profiler 和 cProfiler 类似,区别是 line_profiler 是第三方库,而且它会逐行分析代码的用时,比 cProfiler 更强大。

1. 安装

打开 https://www.lfd.uci.edu/~gohlke/pythonlibs/#line_profiler,下载符合自己 Python 版本的 line_profiler .whl 文件:

1.png

下载完之后打开 cmd ,切换到文件位置,执行以下命令:
pip install {.whl 文件名}

2. 使用方法

下面是 demo.py 的内容(求 100 以内哪两个数相加为 100 的程序,双重 for 循环):
# -*- coding: utf-8 -*-

@profile    # 加 @profile 的函数表示需要进行分析
def demo():
    task = []

    for a in range(0, 101):
        for b in range(0, 101):
            if a + b == 100:
                task.append((a, b))
    return task


if __name__ == '__main__':
    demo()

cmd 执行命令:
kernprof -l -v demo.py

其中 -l 表示逐行分析,-v 表示输出分析结果。

执行这段命令会生成一个 demo.py.lprof,后期可以对该文件进行分析。

分析结果:
Wrote profile results to demo.py.lprof
Timer unit: 1e-07 s

Total time: 0.0065966 s
File: demo.py
Function: demo at line 3

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
     3                                           @profile
     4                                           def demo():
     5         1         69.0     69.0      0.1      task = []
     6
     7       102        287.0      2.8      0.4      for a in range(0, 101):
     8     10302      30200.0      2.9     45.8          for b in range(0, 101):
     9     10201      34938.0      3.4     53.0              if a + b == 100:
    10       101        468.0      4.6      0.7                  task.append((a, b))
    11         1          4.0      4.0      0.0      return task


其中:

  • Total time 表示代码总用时。
  • File 表示分析的文件名。
  • Function 表示测试的函数。
  • Line # 表示行号。
  • Hits 表示本行调用的次数。
  • Time 表示本行总执行时间。
  • Per Hit 表示本行执行一次的用时,是 Time 除以 Hits 的结果。
  • % Time 表示本行代码占了它所在函数的消耗的时间百分比。


可以看出在 demo 函数中最消耗时间的是判断 a + b 是否等于 100,占用了 50.5% 的时间。

之后对代码进行优化:
@profile
def demo():
    task = []

    for a in range(0, 101):
        b = 100 - a
        task.append((a, b))
    return task


if __name__ == '__main__':
    demo()

再次进行分析:
Wrote profile results to demo.py.lprof
Timer unit: 1e-07 s

Total time: 0.0001048 s
File: demo.py
Function: demo at line 3

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
     3                                           @profile
     4                                           def demo():
     5         1         31.0     31.0      3.0      task = []
     6
     7       102        303.0      3.0     28.9      for a in range(0, 101):
     8       101        309.0      3.1     29.5          b = 100 - a
     9       101        402.0      4.0     38.4          task.append((a, b))
    10         1          3.0      3.0      0.3      return task

可以发现总用时及循环体里代码的调用次数减少了。

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-1-1 16:39:30 From FishC Mobile | 显示全部楼层
沙发!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-7-12 18:28:16 | 显示全部楼层
(又是我)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-25 14:56

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表