如何分析 Python 脚本?
- 2024-11-18 08:41:00
- admin 原创
- 13
问题描述:
欧拉计划和其他编程竞赛通常都有最大运行时间,或者人们会吹嘘他们的特定解决方案运行得有多快。对于 Python,有时方法有些笨拙 - 即添加计时代码__main__
。
有什么好方法可以分析 Python 程序运行的时间?
解决方案 1:
Python 包含一个名为 的分析器cProfile
。它不仅提供总运行时间,还分别对每个函数进行计时,并告诉您每个函数被调用了多少次,从而轻松确定应在何处进行优化。
您可以从代码中或从解释器中调用它,如下所示:
import cProfile
cProfile.run('foo()')
更有用的是,你可以在运行脚本时调用 cProfile:
python -m cProfile myscript.py
或者在运行模块时:
python -m cProfile -m mymodule
为了使其更加简单,我创建了一个名为“profile.bat”的小批处理文件:
python -m cProfile %1
所以我所要做的就是运行:
profile euler048.py
我得到了这个:
1007 function calls in 0.061 CPU seconds
Ordered by: standard name
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.061 0.061 <string>:1(<module>)
1000 0.051 0.000 0.051 0.000 euler048.py:2(<lambda>)
1 0.005 0.005 0.061 0.061 euler048.py:2(<module>)
1 0.000 0.000 0.061 0.061 {execfile}
1 0.002 0.002 0.053 0.053 {map}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler objects}
1 0.000 0.000 0.000 0.000 {range}
1 0.003 0.003 0.003 0.003 {sum}
欲了解更多信息,请查看 PyCon 2013 上的这篇教程,标题为
《Python Profiling》
,也可从 YouTube 上观看。
解决方案 2:
不久前,我制作了pycallgraph
一个从 Python 代码生成可视化效果的程序。编辑:我已更新示例以适用于 3.3(撰写本文时的最新版本)。
pip install pycallgraph
安装GraphViz后,您可以从命令行运行它:
pycallgraph graphviz -- ./mypythonscript.py
或者,你可以分析代码的特定部分:
from pycallgraph import PyCallGraph
from pycallgraph.output import GraphvizOutput
with PyCallGraph(output=GraphvizOutput()):
code_to_profile()
上述任何一个操作都会生成pycallgraph.png
类似下图的文件:
解决方案 3:
值得指出的是,使用分析器(默认情况下)仅在主线程上有效,如果您使用其他线程,您将无法从它们获得任何信息。这可能是一个问题,因为分析器文档中完全没有提到这一点。
如果您还想分析线程,您可能需要查看文档中的threading.setprofile()
函数。
您也可以创建自己的threading.Thread
子类来执行此操作:
class ProfiledThread(threading.Thread):
# Overrides threading.Thread.run()
def run(self):
profiler = cProfile.Profile()
try:
return profiler.runcall(threading.Thread.run, self)
finally:
profiler.dump_stats('myprofile-%d.profile' % (self.ident,))
并使用ProfiledThread
该类而不是标准类。这可能会给您带来更多灵活性,但我不确定这样做是否值得,尤其是当您使用不会使用您的类的第三方代码时。
解决方案 4:
最简单、最快捷的方法来查找所有时间都花在了哪里。
1. pip install snakeviz
2. python -m cProfile -o temp.dat <PROGRAM>.py
3. snakeviz temp.dat
在浏览器中绘制饼图。最大的部分是问题函数。非常简单。
解决方案 5:
Python wiki 是一个很棒的资源分析页面:
http://wiki.python.org/moin/PythonSpeed/PerformanceTips#Profiling_Code
与 Python 文档一样:
http: //docs.python.org/library/profile.html
正如 Chris Lawlor 所示,cProfile 是一款出色的工具,可以轻松用于打印到屏幕上:
python -m cProfile -s time mine.py <args>
或提交:
python -m cProfile -o output.file mine.py <args>
PS> 如果你使用的是 Ubuntu,请确保安装 python-profile
apt-get install python-profiler
如果输出到文件,则可以使用以下工具获得很好的可视化效果
PyCallGraph:用于创建调用图图像的工具
安装:
pip install pycallgraph
跑步:
pycallgraph mine.py args
看法:
gimp pycallgraph.png
你可以使用任何你喜欢的方法来查看 png 文件,我使用了 gimp
不幸的是我经常得到
点:图形对于 cairo-renderer 位图来说太大。按 0.257079 缩放以适应
这使得我的图像太小而无法使用。因此我通常创建 svg 文件:
pycallgraph -f svg -o pycallgraph.svg mine.py <args>
PS>确保安装了 graphviz(提供点程序):
pip install graphviz
通过@maxy / @quodlibetor 使用 gprof2dot 进行替代绘图:
pip install gprof2dot
python -m cProfile -o profile.pstats mine.py
gprof2dot -f pstats profile.pstats | dot -Tsvg -o mine.svg
解决方案 6:
@Maxy 对这个答案的评论对我帮助很大,我认为它值得有自己的答案:我已经有了 cProfile 生成的 .pstats 文件,并且我不想用 pycallgraph 重新运行,所以我使用了gprof2dot,并得到了漂亮的 svg:
$ sudo apt-get install graphviz
$ git clone https://github.com/jrfonseca/gprof2dot
$ ln -s "$PWD"/gprof2dot/gprof2dot.py ~/bin
$ cd $PROJECT_DIR
$ gprof2dot.py -f pstats profile.pstats | dot -Tsvg -o callgraph.svg
然后砰!
它使用 dot(与 pycallgraph 使用的相同),因此输出看起来类似。但我的印象是 gprof2dot 丢失的信息较少:
解决方案 7:
在研究这个主题时,我遇到了一款名为SnakeViz的便捷工具。SnakeViz 是一款基于 Web 的分析可视化工具。它非常易于安装和使用。我通常使用它的方式是生成一个统计文件%prun
,然后在 SnakeViz 中进行分析。
所使用的主要 viz 技术是如下所示的Sunburst 图,其中函数调用的层次结构排列为弧层,时间信息以它们的角宽度进行编码。
最好的是您可以与图表进行交互。例如,要放大,可以单击一个弧,然后该弧及其子代将放大为新的旭日图以显示更多细节。
解决方案 8:
cProfile
非常适合进行分析,而kcachegrind
非常适合可视化结果。pyprof2calltree
中间部分处理文件转换。
python -m cProfile -o script.profile script.py
pyprof2calltree -i script.profile -o script.calltree
kcachegrind script.calltree
所需系统包:
kcachegrind
(Linux)、qcachegrind
(MacOs)
在 Ubuntu 上设置:
apt-get install kcachegrind
pip install pyprof2calltree
结果:
解决方案 9:
我最近创建了tuna来可视化 Python 运行时和导入配置文件;这可能会有所帮助。
安装
pip install tuna
创建运行时配置文件
python3 -m cProfile -o program.prof yourfile.py
或导入配置文件(需要 Python 3.7+)
python3 -X importprofile yourfile.py 2> import.log
然后只需在文件上运行 tuna
tuna program.prof
解决方案 10:
同样值得一提的是 GUI cProfile 转储查看器RunSnakeRun。它允许您排序和选择,从而放大程序的相关部分。图片中矩形的大小与所用时间成正比。如果您将鼠标悬停在矩形上,它会在表格和地图上的任何位置突出显示该调用。当您双击矩形时,它会放大该部分。它将向您显示谁调用了该部分以及该部分调用了什么。
描述信息非常有用。它向您显示了该位的代码,这在您处理内置库调用时非常有用。它告诉您在哪个文件和哪一行找到代码。
还想指出,原帖者说的是“分析”,但他似乎指的是“计时”。请记住,分析后程序的运行速度会变慢。
解决方案 11:
配置文件
line_profiler
(已经在这里介绍过)也受到了启发 pprofile
,其描述如下:
行粒度、线程感知的确定性和统计纯 Python 分析器
它提供与 一样的行粒度line_profiler
,是纯 Python,可以用作独立命令或模块,甚至可以生成可用 轻松分析的 callgrind 格式文件[k|q]cachegrind
。
维普罗夫
还有vprof,一个 Python 包,描述如下:
[...] 为各种 Python 程序特性(例如运行时间和内存使用情况)提供丰富且交互式的可视化效果。
解决方案 12:
一个很好的分析模块是 line_profiler(使用脚本 kernprof.py 调用)。可以在此处下载。
我的理解是,cProfile 仅提供有关每个函数所花费的总时间的信息。因此,不会对每行代码进行计时。这在科学计算中是一个问题,因为一行代码通常需要花费大量时间。此外,我记得,cProfile 没有捕捉到我在 numpy.dot 中花费的时间。
解决方案 13:
如果所有这些花哨的 UI 无法安装或运行,则仅限终端(且最简单)的解决方案:完全
忽略cProfile
并将其替换为pyinstrument
,它将在执行后立即收集并显示调用树。
安装:
$ pip install pyinstrument
配置文件和显示结果:
$ python -m pyinstrument ./prog.py
适用于python2和3。
[编辑] 用于仅分析部分代码的 API 文档可在此处找到。
解决方案 14:
使用像austin这样的统计分析器,不需要任何仪器,这意味着你只需使用以下命令就可以从 Python 应用程序获取分析数据
austin python3 my_script.py
原始输出不是很有用,但您可以将其传输到flamegraph.pl
以获取该数据的火焰图表示,该图可以为您提供时间花费(以实时微秒为单位)的细目分类。
austin python3 my_script.py | flamegraph.pl > my_script_profile.svg
或者,您也可以使用 Web 应用程序Speedscope.app快速可视化收集的样本。如果您安装了pprof,您还可以获取austin-python(例如pipx install austin-python
)并使用austin2pprof
转换为 pprof 格式。
但是,如果你安装了 VS Code,则可以使用Austin 扩展获得更具交互性的体验,其中包含源代码热图、顶级函数和收集的调用堆栈
如果您宁愿使用终端,您也可以使用 TUI ,它也具有实时图形模式:
解决方案 15:
有很多很好的答案,但他们要么使用命令行,要么使用一些外部程序来分析和/或对结果进行排序。
我真的很怀念可以在 IDE(eclipse-PyDev)中使用而无需触碰命令行或安装任何东西的方法。所以就在这里。
无需命令行
def count():
from math import sqrt
for x in range(10**5):
sqrt(x)
if __name__ == '__main__':
import cProfile, pstats
cProfile.run("count()", "{}.profile".format(__file__))
s = pstats.Stats("{}.profile".format(__file__))
s.strip_dirs()
s.sort_stats("time").print_stats(10)
请参阅文档或其他答案以获取更多信息。
解决方案 16:
根据 Joe Shaw 关于多线程代码无法按预期工作的回答,我发现runcall
cProfile 中的方法只是在执行self.enable()
并self.disable()
调用被分析的函数调用,因此您可以自己简单地执行此操作,并在两者之间添加您想要的任何代码,同时尽量减少对现有代码的干扰。
解决方案 17:
用于在 IPython 笔记本上快速获取配置文件统计信息。可以将line_profiler和memory_profiler直接嵌入到笔记本中。
另一个有用的包是Pympler。它是一个功能强大的分析包,能够跟踪类、对象、函数、内存泄漏等。示例如下,文档已附上。
得到它!
!pip install line_profiler
!pip install memory_profiler
!pip install pympler
加载它!
%load_ext line_profiler
%load_ext memory_profiler
使用它!
%时间
%time print('Outputs CPU time,Wall Clock time')
#CPU times: user 2 µs, sys: 0 ns, total: 2 µs Wall time: 5.96 µs
给出:
CPU times:CPU级别执行时间
sys times:系统级执行时间
总计:CPU 时间 + 系统时间
挂钟时间:挂钟时间
%时间
%timeit -r 7 -n 1000 print('Outputs execution time of the snippet')
#1000 loops, best of 7: 7.46 ns per loop
给出循环(n)次中给定运行次数(r)的最佳时间。
输出系统缓存的详细信息:
当代码片段被多次执行时,系统会缓存一些操作并且不会再次执行它们,这可能会影响配置文件报告的准确性。
%prun
%prun -s cumulative 'Code to profile'
给出:
函数调用次数 (ncalls)
每个函数调用都有条目(不同)
每次呼叫所用时间(percall)
函数调用前经过的时间(cumtime)
所调用函数/模块的名称等...
%memit
%memit 'Code to profile'
#peak memory: 199.45 MiB, increment: 0.00 MiB
给出:
内存使用情况
%lprun
#Example function
def fun():
for i in range(10):
print(i)
#Usage: %lprun <name_of_the_function> function
%lprun -f fun fun()
给出:
逐行统计
系统获取sizeof
sys.getsizeof('code to profile')
# 64 bytes
以字节为单位返回对象的大小。
来自 pympler 的 asizeof()
from pympler import asizeof
obj = [1,2,("hey","ha"),3]
print(asizeof.asizeof(obj,stats=4))
pympler.asizeof 可用于调查某些 Python 对象消耗的内存量。与 sys.getsizeof 不同,asizeof 以递归方式确定对象的大小
来自 pympler 的跟踪器
from pympler import tracker
tr = tracker.SummaryTracker()
def fun():
li = [1,2,3]
di = {"ha":"haha","duh":"Umm"}
fun()
tr.print_diff()
跟踪函数的生命周期。
Pympler 软件包包含大量用于分析代码的实用函数。本文无法一一介绍。请参阅随附的文档以了解详细的分析实现。
Pympler文档
解决方案 18:
line_profiler
最近我为 PyCharm 创建了一个插件,您可以使用它轻松地在 PyCharm 编辑器中分析和可视化结果。
line_profiler
其他答案中也提到过,它是一个很好的工具,可以准确分析 Python 解释器在某些行上花费了多少时间。
我创建的 PyCharm 插件可以在这里找到:
https ://plugins.jetbrains.com/plugin/16536-line-profiler
它需要您 Python 环境中的一个名为的辅助包line-profiler-pycharm
,可以使用 pip 或插件本身进行安装。
在PyCharm中安装插件后:
line_profiler_pycharm.profile
使用装饰器来装饰你想要分析的任何函数与“Profile Lines”跑步者一起奔跑
结果截图:
解决方案 19:
在 Virtaal 的源代码中有一个非常有用的类和装饰器,可以非常轻松地进行分析(即使针对特定方法/函数)。然后可以在 KCacheGrind 中非常方便地查看输出。
解决方案 20:
如果您想制作一个累积分析器,这意味着连续运行该函数几次并观察结果的总和。
你可以使用这个cumulative_profiler
装饰器:
它是 python >= 3.6 特有的,但你可以删除nonlocal
它以便在旧版本上运行。
import cProfile, pstats
class _ProfileFunc:
def __init__(self, func, sort_stats_by):
self.func = func
self.profile_runs = []
self.sort_stats_by = sort_stats_by
def __call__(self, *args, **kwargs):
pr = cProfile.Profile()
pr.enable() # this is the profiling section
retval = self.func(*args, **kwargs)
pr.disable()
self.profile_runs.append(pr)
ps = pstats.Stats(*self.profile_runs).sort_stats(self.sort_stats_by)
return retval, ps
def cumulative_profiler(amount_of_times, sort_stats_by='time'):
def real_decorator(function):
def wrapper(*args, **kwargs):
nonlocal function, amount_of_times, sort_stats_by # for python 2.x remove this row
profiled_func = _ProfileFunc(function, sort_stats_by)
for i in range(amount_of_times):
retval, ps = profiled_func(*args, **kwargs)
ps.print_stats()
return retval # returns the results of the function
return wrapper
if callable(amount_of_times): # incase you don't want to specify the amount of times
func = amount_of_times # amount_of_times is the function in here
amount_of_times = 5 # the default amount
return real_decorator(func)
return real_decorator
例子
分析函数baz
import time
@cumulative_profiler
def baz():
time.sleep(1)
time.sleep(2)
return 1
baz()
baz
运行5次并打印以下内容:
20 function calls in 15.003 seconds
Ordered by: internal time
ncalls tottime percall cumtime percall filename:lineno(function)
10 15.003 1.500 15.003 1.500 {built-in method time.sleep}
5 0.000 0.000 15.003 3.001 <ipython-input-9-c89afe010372>:3(baz)
5 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
指定次数
@cumulative_profiler(3)
def baz():
...
解决方案 21:
我刚刚受 pypref_time 的启发开发了自己的分析器:
https://github.com/modaresimr/auto_profiler
更新版本 2
安装:
pip install auto_profiler
快速入门:
from auto_profiler import Profiler
with Profiler():
your_function()
在 Jupyter 中使用,可以实时查看运行时间
更新版本 1
通过添加装饰器,它将显示耗时函数树
@Profiler(depth=4)
Install by: pip install auto_profiler
例子
import time # line number 1
import random
from auto_profiler import Profiler, Tree
def f1():
mysleep(.6+random.random())
def mysleep(t):
time.sleep(t)
def fact(i):
f1()
if(i==1):
return 1
return i*fact(i-1)
def main():
for i in range(5):
f1()
fact(3)
with Profiler(depth=4):
main()
示例输出
Time [Hits * PerHit] Function name [Called from] [function location]
-----------------------------------------------------------------------
8.974s [1 * 8.974] main [auto-profiler/profiler.py:267] [/test/t2.py:30]
├── 5.954s [5 * 1.191] f1 [/test/t2.py:34] [/test/t2.py:14]
│ └── 5.954s [5 * 1.191] mysleep [/test/t2.py:15] [/test/t2.py:17]
│ └── 5.954s [5 * 1.191] <time.sleep>
|
|
| # The rest is for the example recursive function call fact
└── 3.020s [1 * 3.020] fact [/test/t2.py:36] [/test/t2.py:20]
├── 0.849s [1 * 0.849] f1 [/test/t2.py:21] [/test/t2.py:14]
│ └── 0.849s [1 * 0.849] mysleep [/test/t2.py:15] [/test/t2.py:17]
│ └── 0.849s [1 * 0.849] <time.sleep>
└── 2.171s [1 * 2.171] fact [/test/t2.py:24] [/test/t2.py:20]
├── 1.552s [1 * 1.552] f1 [/test/t2.py:21] [/test/t2.py:14]
│ └── 1.552s [1 * 1.552] mysleep [/test/t2.py:15] [/test/t2.py:17]
└── 0.619s [1 * 0.619] fact [/test/t2.py:24] [/test/t2.py:20]
└── 0.619s [1 * 0.619] f1 [/test/t2.py:21] [/test/t2.py:14]
解决方案 22:
cProfile 非常适合快速分析,但大多数时候它都以错误结束。函数 runctx 通过正确初始化环境和变量解决了这个问题,希望它对某些人有用:
import cProfile
cProfile.runctx('foo()', None, locals())
解决方案 23:
gprof2dot_magic
魔法函数用于gprof2dot
将任何 Python 语句在 JupyterLab 或 Jupyter Notebook 中分析为 DOT 图。
GitHub 仓库:https://github.com/mattijn/gprof2dot_magic
安装
确保您有 Python 包gprof2dot_magic
。
pip install gprof2dot_magic
它的依赖项gprof2dot
也graphviz
将被安装
用法
要启用魔法功能,首先加载gprof2dot_magic
模块
%load_ext gprof2dot_magic
然后将任意线语句分析为如下 DOT 图:
%gprof2dot print('hello world')
解决方案 24:
我的方法是使用 yappi ( https://github.com/sumerc/yappi )。它与 RPC 服务器结合使用特别有用,在 RPC 服务器中(即使只是为了调试)您可以注册方法来启动、停止和打印分析信息,例如通过这种方式:
@staticmethod
def startProfiler():
yappi.start()
@staticmethod
def stopProfiler():
yappi.stop()
@staticmethod
def printProfiler():
stats = yappi.get_stats(yappi.SORTTYPE_TTOT, yappi.SORTORDER_DESC, 20)
statPrint = '
'
namesArr = [len(str(stat[0])) for stat in stats.func_stats]
log.debug("namesArr %s", str(namesArr))
maxNameLen = max(namesArr)
log.debug("maxNameLen: %s", maxNameLen)
for stat in stats.func_stats:
nameAppendSpaces = [' ' for i in range(maxNameLen - len(stat[0]))]
log.debug('nameAppendSpaces: %s', nameAppendSpaces)
blankSpace = ''
for space in nameAppendSpaces:
blankSpace += space
log.debug("adding spaces: %s", len(nameAppendSpaces))
statPrint = statPrint + str(stat[0]) + blankSpace + " " + str(stat[1]).ljust(8) + " " + str(
round(stat[2], 2)).ljust(8 - len(str(stat[2]))) + " " + str(round(stat[3], 2)) + "
"
log.log(1000, "
name" + ''.ljust(maxNameLen - 4) + " ncall ttot tsub")
log.log(1000, statPrint)
然后,当您的程序工作时,您可以随时通过调用startProfiler
RPC 方法启动分析器,并通过调用将分析信息转储到日志文件printProfiler
(或修改 rpc 方法将其返回给调用者)并得到这样的输出:
2014-02-19 16:32:24,128-|SVR-MAIN |-(Thread-3 )-Level 1000:
name ncall ttot tsub
2014-02-19 16:32:24,128-|SVR-MAIN |-(Thread-3 )-Level 1000:
C:Python27libsched.py.run:80 22 0.11 0.05
M:_documents_repos 9_aheadReposappsahdModbusSrvpyAheadRpcSrvxmlRpc.py.iterFnc:293 22 0.11 0.0
M:_documents_repos 9_aheadReposappsahdModbusSrvserverMain.py.makeIteration:515 22 0.11 0.0
M:_documents_repos 9_aheadReposappsahdModbusSrvpyAheadRpcSrvPicklingXMLRPC.py._dispatch:66 1 0.0 0.0
C:Python27libBaseHTTPServer.py.date_time_string:464 1 0.0 0.0
c:/userszasiec~1appdatalocal empeasy_install-hwcsr1psutil-1.1.2-py2.7-win32.egg.tmppsutil_psmswindows.py._get_raw_meminfo:243 4 0.0 0.0
C:Python27libSimpleXMLRPCServer.py.decode_request_content:537 1 0.0 0.0
c:/userszasiec~1appdatalocal empeasy_install-hwcsr1psutil-1.1.2-py2.7-win32.egg.tmppsutil_psmswindows.py.get_system_cpu_times:148 4 0.0 0.0
<string>.__new__:8 220 0.0 0.0
C:Python27libsocket.py.close:276 4 0.0 0.0
C:Python27lib hreading.py.__init__:558 1 0.0 0.0
<string>.__new__:8 4 0.0 0.0
C:Python27lib hreading.py.notify:372 1 0.0 0.0
C:Python27lib
fc822.py.getheader:285 4 0.0 0.0
C:Python27libBaseHTTPServer.py.handle_one_request:301 1 0.0 0.0
C:Python27libxmlrpclib.py.end:816 3 0.0 0.0
C:Python27libSimpleXMLRPCServer.py.do_POST:467 1 0.0 0.0
C:Python27libSimpleXMLRPCServer.py.is_rpc_path_valid:460 1 0.0 0.0
C:Python27libSocketServer.py.close_request:475 1 0.0 0.0
c:/userszasiec~1appdatalocal empeasy_install-hwcsr1psutil-1.1.2-py2.7-win32.egg.tmppsutil__init__.py.cpu_times:1066 4 0.0 0.0
对于短脚本来说它可能不是很有用,但有助于优化服务器类型的进程,特别是考虑到该printProfiler
方法可以随着时间的推移被多次调用来分析和比较不同的程序使用场景。
在较新版本的 yappi 中,以下代码将起作用:
@staticmethod
def printProfile():
yappi.get_func_stats().print_all()
解决方案 25:
处理 Python 中分析的新工具是 PyVmMonitor: http: //www.pyvmmonitor.com/
它具有一些独特的功能,例如
将分析器附加到正在运行的 (CPython) 程序
通过 Yappi 集成进行按需分析
在另一台机器上进行分析
多进程支持(multiprocessing、django……)
实时采样/CPU 视图(带时间范围选择)
通过 cProfile/profile 集成进行确定性分析
分析现有的 PStats 结果
打开 DOT 文件
程序化 API 访问
按方法或生产线对样品进行分组
PyDev 集成
PyCharm 集成
注意:它是商业的,但是开源是免费的。
解决方案 26:
Scalene 是一个新的 Python 分析器,涵盖了许多用例,并且对性能的影响极小:
https://github.com/plasma-umass/scalene
它可以非常精细地分析 CPU、GPU 和内存的使用情况。它还特别支持多线程/并行 Python 代码。
解决方案 27:
要添加到https://stackoverflow.com/a/582337/1070617,
我编写了这个模块,它允许您使用 cProfile 并轻松查看其输出。更多信息请访问:https: //github.com/ymichael/cprofilev
$ python -m cprofilev /your/python/program
# Go to http://localhost:4000 to view collected statistics.
另请参阅: http: //ymichael.com/2014/03/08/profiling-python-with-cprofile.html,了解如何理解收集到的统计数据。
解决方案 28:
这取决于您想从分析中看到什么。 (bash) 可以提供简单的时间指标。
time python python_prog.py
甚至‘/usr/bin/time’也可以通过使用‘--verbose’标志输出详细指标。
要检查每个函数给出的时间指标并更好地了解函数花费了多少时间,您可以使用 python 中内置的 cProfile。
进入更详细的指标(如性能),时间并不是唯一的指标。您可以关注内存、线程等。
分析选项:
line_profiler是另一种常用的分析器,用于逐行找出时间指标。2
. memory_profiler是一种分析内存使用情况的工具。3
. heapy(来自 Guppy 项目)分析堆中对象的使用方式。
这些是我倾向于使用的一些常用方法。但如果你想了解更多,请尝试阅读这本书。
这是一本关于性能入门的非常好的书。你可以转到使用 Cython 和 JIT(即时)编译的 Python 的高级主题。
解决方案 29:
想知道 Python 脚本到底在做什么吗?使用 Inspect Shell。Inspect Shell 可让您打印/更改全局变量并运行函数,而无需中断正在运行的脚本。现在具有自动完成和命令历史记录(仅在 Linux 上)。
Inspect Shell 不是 pdb 风格的调试器。
https://github.com/amoffat/Inspect-Shell
您可以使用它(和您的手表)。
解决方案 30:
还有一个名为 的统计分析器statprof
。它是一个采样分析器,因此它给您的代码带来的开销最小,并且提供基于行(而不仅仅是基于函数)的计时。它更适合游戏等软实时应用程序,但精度可能低于 cProfile。
pypi 中的版本有点旧,因此可以pip
通过指定git 存储库来安装它:
pip install git+git://github.com/bos/statprof.py@1a33eba91899afe17a8b752c6dfdec6f05dd0c01
你可以像这样运行它:
import statprof
with statprof.profile():
my_questionable_function()
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件