LineProfiler 是专为定位函数内“哪一行最慢”设计的轻量级逐行性能分析工具,适用于已知慢在某函数但需精确定位瓶颈行的场景。

LineProfiler 是什么,什么时候该用它
LineProfiler 是一个轻量级的 Python 逐行性能分析工具,专为定位「哪一行代码最慢」而设计。它不替代 cProfile,而是补充:当你已经知道慢在某个函数里,但不确定是循环体、条件分支还是某次 API 调用拖了后腿时,LineProfiler 才真正有用。
它通过字节码插桩实现,对目标函数加装饰器后运行,输出每行执行次数和耗时(单位:毫秒)。不支持异步函数、C 扩展函数,也不统计子调用开销(只统计本函数内各行)。
注意:它不能分析交互式环境(如 Jupyter cell)中动态定义的函数,必须是模块中可 import 的函数。
安装与基本使用流程
先确保已安装:
pip install line_profiler
立即学习“Python免费学习笔记(深入)”;
然后分三步走:
- 用
@profile装饰你想分析的函数(不需要 import,line_profiler 安装后自动注入该装饰器) - 用命令行运行:
python -m line_profiler your_script.py
- 或者在脚本末尾手动触发:
from line_profiler import LineProfiler<br>lp = LineProfiler()<br>lp.add_function(your_target_function)<br>lp.run('your_target_function()')<br>lp.print_stats()
常见错误:直接运行 python your_script.py 不会触发分析;漏掉 -m line_profiler 就等于白加 @profile。
@profile 装饰器的限制与绕过方法
@profile 只识别顶层函数,对嵌套函数、lambda、类方法(除非显式加在方法上)默认无效。比如:
class A:<br> def method(self):<br> @profile # ✅ 这样可以<br> def inner():<br> pass
但更常见的坑是:函数在 if 分支里定义,或由工厂函数返回——这些都无法被 line_profiler 自动发现。
解决办法只有两个:
- 把待测函数移到模块顶层
- 改用
LineProfiler().add_function(func)显式注册(推荐用于测试脚本)
别忘了:加了 @profile 但没用 line_profiler 运行,代码照常执行,无任何报错,也不会提示你“装饰器没生效”。
解读输出结果的关键列含义
典型输出长这样:
Line # Hits Time Per Hit % Time Line Contents<br>==============================================================<br> 10 1 5.2 5.2 0.1 def slow_func():<br> 11 1 0.1 0.1 0.0 total = 0<br> 12 1001 1200.3 1.2 23.5 for i in range(1000):<br> 13 1000 3900.7 3.9 76.4 total += expensive_calc(i)
重点关注三列:
-
Hits:该行被执行次数(比如循环体内的行,Hits 往往远大于 1) -
Time:该行总耗时(单位:微秒,不是毫秒!文档写错,实测是 µs) -
% Time:占整个函数总耗时的百分比
容易忽略的点:Time 是纯该行执行时间,不含其调用的函数内部耗时;所以如果某行是 result = requests.get(...),Time 只含发起请求前的准备开销,不包括网络等待——这点和直觉相反,务必记住。



















