Python line_profiler 性能分析库,相比于 cProfile,输出更为直观.

材料主要出处:python性能分析之line_profiler模块 - 2019.01.04

line_profiler使用装饰器(@profile)标记需要调试的函数. 用 kernprof.py 脚本运行代码, 被选函数每一行花费的 cpu 时间以及其他信息就会被记录下来.

1. 安装

pip install Cpython
pip install Cython git+https://github.com/rkern/line_profiler.git
#或
pip install line-profiler

2. 使用

在需要评估性能的函数前加上 @profile,形式如:

@profile
def fun():
    pass

@profile
def main():
    pass

if __name__ == '__main__':
    main()

其中,@profile 只是一个标记,不是 Python 的语句,所以会导致代码不能直接运行,只能用专门的方法运行:

kernprof -l -v xxxxxx.py

-l 表示逐行分析, -v 用于输出。同时会输出一个后缀为.py.lprof 的文件,后期可以对.lprof文件进行分析.

注:@profile 用法有一点限制,不可以用于 class ,但是可以用于class 的方法上;子函数也可以用;并且可以同时 profile 多个函数.

3. 示例

loopdemo.py:

@profile
def foo():
    task = []

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


@profile
def run():
    for item in foo():
        pass


if __name__ == '__main__':
    run()

运行:

kernprof -l -v loopdemo.py

输出结果形式如:

Wrote profile results to loopdemo.py.lprof
Timer unit: 1e-06 s

Total time: 0.009856 s
File: loopdemo.py
Function: foo at line 1

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
     1                                           @profile
     2                                           def foo():
     3         1          1.0      1.0      0.0      task = []
     4
     5       102         47.0      0.5      0.5      for a in range(0, 101):
     6     10302       4741.0      0.5     48.1          for b in range(0, 101):
     7     10201       4975.0      0.5     50.5              if a + b == 100:
     8       101         91.0      0.9      0.9                  task.append((a, b))
     9         1          1.0      1.0      0.0      return task

Total time: 0.017778 s
File: loopdemo.py
Function: run at line 12

Line #      Hits         Time  Per Hit   % Time  Line Contents
==============================================================
    12                                           @profile
    13                                           def run():
    14       102      17747.0    174.0     99.8      for item in foo():
    15       101         31.0      0.3      0.2          pass

其中,

[1] - Total time,总耗时

[2] - Hits,调用次数

[3] - %Time 列,指出哪行代码占了它所在函数的消耗的时间百分比.

Last modification:April 13th, 2021 at 09:02 am