鱼C论坛

 找回密码
 立即注册
查看: 2651|回复: 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 ,切换到文件位置,执行以下命令:

  1. pip install {.whl 文件名}
复制代码


2. 使用方法

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

  1. # -*- coding: utf-8 -*-

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

  5.     for a in range(0, 101):
  6.         for b in range(0, 101):
  7.             if a + b == 100:
  8.                 task.append((a, b))
  9.     return task


  10. if __name__ == '__main__':
  11.     demo()
复制代码


cmd 执行命令:

  1. kernprof -l -v demo.py
复制代码


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

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

分析结果:

  1. Wrote profile results to demo.py.lprof
  2. Timer unit: 1e-07 s

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

  6. Line #      Hits         Time  Per Hit   % Time  Line Contents
  7. ==============================================================
  8.      3                                           @profile
  9.      4                                           def demo():
  10.      5         1         69.0     69.0      0.1      task = []
  11.      6
  12.      7       102        287.0      2.8      0.4      for a in range(0, 101):
  13.      8     10302      30200.0      2.9     45.8          for b in range(0, 101):
  14.      9     10201      34938.0      3.4     53.0              if a + b == 100:
  15.     10       101        468.0      4.6      0.7                  task.append((a, b))
  16.     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% 的时间。

之后对代码进行优化:

  1. @profile
  2. def demo():
  3.     task = []

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


  8. if __name__ == '__main__':
  9.     demo()
复制代码


再次进行分析:

  1. Wrote profile results to demo.py.lprof
  2. Timer unit: 1e-07 s

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

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


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

本帖被以下淘专辑推荐:

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-1-1 16:39:30 From FishC Mobile | 显示全部楼层
沙发!
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-7-12 18:28:16 | 显示全部楼层
(又是我)
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-5-26 10:43

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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