line_profiler需pip安装并用kernprof运行,仅分析@profile标记的函数;time为单次执行纳秒均值,%time为占该函数总耗时百分比;不可与memory_profiler混用装饰器。

line_profiler 安装和基本命令行用法
line_profiler 不是 Python 自带模块,必须单独安装,且不能直接用 python -m line_profiler 运行——它依赖一个编译后的 C 扩展,纯 pip install 后还需额外注册装饰器或使用专用命令。
正确安装方式是:
- 运行
pip install line_profiler - 如果用 ipython/jupyter,再执行
ipython install --user --kernel-name python3 --extensions line_profiler(否则%lprun会报错) - 命令行分析脚本时,必须用
kernprof -l -v script.py,其中-l表示启用 line-by-line profiling,-v表示立即打印结果;漏掉-l就不会收集行级数据
@profile 装饰器必须显式添加且不可省略
line_profiler 不会自动分析所有函数,它只追踪被 @profile 标记的函数。这个装饰器不是内置的,也不来自 line_profiler 模块本身——它由 kernprof 在运行时动态注入,所以你代码里写的 @profile 在平时执行会报 NameError: name 'profile' is not defined,这是正常现象,不必加 try/except 或提前导入。
关键点:
- 只需在想分析的函数上方写
@profile,不加括号,不 import 任何东西 - 只能标记函数,不能标记类、模块或 if 块
- 如果分析多个函数,每个都得单独加
@profile;只加一个,其他函数的行耗时就完全不会出现 - 示例:
@profile def heavy_calc(): total = 0 for i in range(100000): total += i ** 2 return total
输出结果中 Time 和 % Time 容易误读
运行 kernprof -l -v script.py 后,终端输出的表格里有三列关键数字:Line、Time、% Time。这里的 Time 单位是纳秒(ns),但它是该行**被调用一次**的平均耗时,不是累计值;而 % Time 是“该行耗时占整个被 profile 函数总耗时的百分比”,不是占全局的百分比。
常见误解:
- 看到某行
Time=500000就以为是 0.5ms —— 实际是 500μs,且前提是这行被执行了一次;若在循环里,真实开销得乘以执行次数 -
% Time高不一定代表该行是瓶颈,比如time.sleep(1)占 99%,但显然不该优化它 - 函数调用行(如
result = another_func())显示的时间包含被调用函数内部全部执行时间,无法穿透——除非你也给another_func加了@profile
与 memory_profiler 混用会失效
很多人想同时看时间和内存,于是写 @profile + @memory_profiler.profile 叠加装饰器。这会导致 line_profiler 完全不工作:kernprof 找不到原始函数对象,最终输出全是 0 行或直接跳过。
替代方案只有两个:
- 分两次跑:
kernprof -l -v script.py看时间,再用python -m memory_profiler script.py看内存 - 改用
psutil手动打点测内存峰值,配合time.perf_counter()做粗粒度时间对比,虽然不够逐行,但至少不冲突
line_profiler 的核心限制在于它靠 AST 重写和字节码插桩实现,一旦函数被其他装饰器包装过,它的 hook 就失效了——这点在封装工具链时特别容易踩空。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











