Python 我如何使用 line_profiler(来自 Robert Kern)?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23885147/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I use line_profiler (from Robert Kern)?
提问by Alex Tereshenkov
I have tried using the line_profiler module for getting a line-by-line profile over a Python file. This is what I've done so far:
我曾尝试使用 line_profiler 模块通过 Python 文件获取逐行配置文件。这是我到目前为止所做的:
1) Installed line_profiler from pypiby using the .exe file (I am on WinXP and Win7). Just clicked through the installation wizard.
1)使用.exe文件从pypi安装line_profiler (我在WinXP和Win7上)。只需单击安装向导即可。
2) Written a small piece of code (similar to what has been asked in another answered question here).
2)编写一小段代码(类似于此处另一个已回答的问题中提出的问题)。
from line_profiler import LineProfiler
def do_stuff(numbers):
print numbers
numbers = 2
profile = LineProfiler(do_stuff(numbers))
profile.print_stats()
3) Run the code from IDLE/PyScripter. I got only the time.
3) 从 IDLE/PyScripter 运行代码。我只有时间。
Timer unit: 4.17188e-10 s
How do I get full line-by-line profile over the code I execute? I have never used any advanced Python features like decorators, so it is hard for me to understand how shall I use the guidelines provided by several posts like hereand here.
如何在我执行的代码上获得完整的逐行配置文件?我从未使用过像装饰器这样的任何高级 Python 功能,所以我很难理解我应该如何使用这里和这里等几篇文章提供的指南。
采纳答案by martineau
Just follow Dan Riti's example from the first link, but use your code. All you have to do after installing the line_profilermodule is add a @profiledecorator right before each function you wish to profile line-by-line and make sure each one is called at least once somewhere else in the code—so for your trivial example code that would be something like this:
只需从第一个链接中遵循 Dan Riti 的示例,但使用您的代码。安装line_profiler模块后,您要做的就是@profile在您希望逐行分析的每个函数之前添加一个装饰器,并确保每个函数在代码中的其他地方至少被调用一次 - 因此对于您的琐碎示例代码是这样的:
example.pyfile:
example.py文件:
@profile
def do_stuff(numbers):
print numbers
numbers = 2
do_stuff(numbers)
Having done that, run your script via the kernprof.py?that was installed in your C:\Python27\Scriptsdirectory. Here's the (not very interesting) actual output from doing this in a Windows 7 command-line session:
完成后,通过kernprof.py? 安装在您的C:\Python27\Scripts目录中。这是在 Windows 7 命令行会话中执行此操作的(不是很有趣的)实际输出:
> python "C:\Python27\Scripts\kernprof.py" -l -v example.py
2
Wrote profile results to example.py.lprof
Timer unit: 3.2079e-07 s
File: example.py
Function: do_stuff at line 2
Total time: 0.00185256 s
Line # Hits Time Per Hit % Time Line Contents
==============================================================
1 @profile
2 def do_stuff(numbers):
3 1 5775 5775.0 100.0 print numbers
You likely need to adapt this last step—the running of your test script with kernprof.pyinstead of directly by the Python interpreter—in order to do the equivalent from within IDLE or PyScripter.
您可能需要调整这最后一步——使用kernprof.pyPython 解释器而不是直接通过 Python 解释器运行测试脚本——以便在 IDLE 或 PyScripter 中执行等效操作。
?Update
? 更新
It appears that in line_profilerv1.0, the kernprofutility is distributed as an executable, not a .pyscript file as it was when I wrote the above. This means the following now needs to used to invoke it from the command-line:
似乎在line_profilerv1.0 中,该kernprof实用程序作为可执行文件分发,而不是.py像我写上述内容时那样的脚本文件。这意味着现在需要使用以下内容从命令行调用它:
> "C:\Python27\Scripts\kernprof.exe" -l -v example.py
回答by tdube
This answer is a copy of my answer herefor how to get line_profilerstatistics from within a Python script (without using kernproffrom the command line or having to add @profiledecorators to functions and class methods). All answers (that I've seen) to similar line_profilerquestions only describe using kernprof.
这个答案是我在此处如何line_profiler从 Python 脚本中获取统计信息的答案的副本(无需kernprof从命令行使用或必须@profile向函数和类方法添加装饰器)。类似line_profiler问题的所有答案(我见过的)仅描述使用kernprof.
The line_profilertest cases (found on GitHub) have an example of how to generate profile data from within a Python script. You have to wrap the function that you want to profile and then call the wrapper passing any desired function arguments.
该line_profiler试验例(关于发现的GitHub)对如何从一个Python脚本内生成描述文件数据的一例。您必须包装要分析的函数,然后通过任何所需的函数参数调用包装器。
from line_profiler import LineProfiler
import random
def do_stuff(numbers):
s = sum(numbers)
l = [numbers[i]/43 for i in range(len(numbers))]
m = ['hello'+str(numbers[i]) for i in range(len(numbers))]
numbers = [random.randint(1,100) for i in range(1000)]
lp = LineProfiler()
lp_wrapper = lp(do_stuff)
lp_wrapper(numbers)
lp.print_stats()
Output:
输出:
Timer unit: 1e-06 s
Total time: 0.000649 s
File: <ipython-input-2-2e060b054fea>
Function: do_stuff at line 4
Line # Hits Time Per Hit % Time Line Contents
==============================================================
4 def do_stuff(numbers):
5 1 10 10.0 1.5 s = sum(numbers)
6 1 186 186.0 28.7 l = [numbers[i]/43 for i in range(len(numbers))]
7 1 453 453.0 69.8 m = ['hello'+str(numbers[i]) for i in range(len(numbers))]
Adding Additional Functions to Profile
向配置文件添加附加功能
Also, you can add additional functions to be profiled as well. For example, if you had a second calledfunction and you only wrap the callingfunction, you'll only see the profile results from the callingfunction.
此外,您还可以添加要分析的其他功能。例如,如果您有第二个被调用的函数并且您只包装了调用函数,您将只能看到来自调用函数的配置文件结果。
from line_profiler import LineProfiler
import random
def do_other_stuff(numbers):
s = sum(numbers)
def do_stuff(numbers):
do_other_stuff(numbers)
l = [numbers[i]/43 for i in range(len(numbers))]
m = ['hello'+str(numbers[i]) for i in range(len(numbers))]
numbers = [random.randint(1,100) for i in range(1000)]
lp = LineProfiler()
lp_wrapper = lp(do_stuff)
lp_wrapper(numbers)
lp.print_stats()
The above would only produce the following profile output for the callingfunction:
以上只会为调用函数生成以下配置文件输出:
Timer unit: 1e-06 s
Total time: 0.000773 s
File: <ipython-input-3-ec0394d0a501>
Function: do_stuff at line 7
Line # Hits Time Per Hit % Time Line Contents
==============================================================
7 def do_stuff(numbers):
8 1 11 11.0 1.4 do_other_stuff(numbers)
9 1 236 236.0 30.5 l = [numbers[i]/43 for i in range(len(numbers))]
10 1 526 526.0 68.0 m = ['hello'+str(numbers[i]) for i in range(len(numbers))]
In this case, you can add the additional calledfunction to profile like this:
在这种情况下,您可以将额外的调用函数添加到配置文件中,如下所示:
from line_profiler import LineProfiler
import random
def do_other_stuff(numbers):
s = sum(numbers)
def do_stuff(numbers):
do_other_stuff(numbers)
l = [numbers[i]/43 for i in range(len(numbers))]
m = ['hello'+str(numbers[i]) for i in range(len(numbers))]
numbers = [random.randint(1,100) for i in range(1000)]
lp = LineProfiler()
lp.add_function(do_other_stuff) # add additional function to profile
lp_wrapper = lp(do_stuff)
lp_wrapper(numbers)
lp.print_stats()
Output:
输出:
Timer unit: 1e-06 s
Total time: 9e-06 s
File: <ipython-input-4-dae73707787c>
Function: do_other_stuff at line 4
Line # Hits Time Per Hit % Time Line Contents
==============================================================
4 def do_other_stuff(numbers):
5 1 9 9.0 100.0 s = sum(numbers)
Total time: 0.000694 s
File: <ipython-input-4-dae73707787c>
Function: do_stuff at line 7
Line # Hits Time Per Hit % Time Line Contents
==============================================================
7 def do_stuff(numbers):
8 1 12 12.0 1.7 do_other_stuff(numbers)
9 1 208 208.0 30.0 l = [numbers[i]/43 for i in range(len(numbers))]
10 1 474 474.0 68.3 m = ['hello'+str(numbers[i]) for i in range(len(numbers))]
NOTE: Adding functions to profile in this way does not require changes to the profiled code (i.e., no need to add @profiledecorators).
注意:以这种方式向配置文件添加函数不需要更改配置文件的代码(即,不需要添加@profile装饰器)。

