如何分析Python脚本?

Chr*_*lor 1203 python performance profiling time-complexity

项目欧拉和其他编码竞赛通常有最长的运行时间或人们吹嘘他们的特定解决方案运行的速度.使用python,有时候这些方法有点像kludgey - 即添加时间码__main__.

分析python程序运行多长时间的好方法是什么?

Chr*_*lor 1282

Python包含一个名为cProfile的探查器.它不仅给出了总运行时间,还给出了每个函数的单独时间,并告诉您每个函数被调用了多少次,这样可以很容易地确定应该在哪里进行优化.

您可以在代码中或从解释器中调用它,如下所示:

import cProfile
cProfile.run('foo()')
Run Code Online (Sandbox Code Playgroud)

更有用的是,您可以在运行脚本时调用cProfile:

python -m cProfile myscript.py
Run Code Online (Sandbox Code Playgroud)

为了使它更容易,我制作了一个名为'profile.bat'的小批处理文件:

python -m cProfile %1
Run Code Online (Sandbox Code Playgroud)

所以我要做的就是运行:

profile euler048.py
Run Code Online (Sandbox Code Playgroud)

我得到了这个:

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}
Run Code Online (Sandbox Code Playgroud)

编辑:更新了PyCon 2013的视频资源链接,名为 Python Profiling,
也是通过YouTube.

  • 对结果进行排序也很有用,可以通过-s开关来完成,例如:' - time'.您可以使用累积/名称/时间/文件排序选项. (247认同)
  • 用于可视化cProfile转储(由`python -m cProfile -o <out.profile> <script>`创建),[RunSnakeRun](http://www.vrplumber.com/programming/runsnakerun/),作为`runsnake <调用out.profile>`非常宝贵. (51认同)
  • 值得注意的是,您可以使用魔术函数%prun(profile run)从ipython中使用cProfile模块.首先导入你的模块,然后用%prun:import euler048调用main函数; %prun euler048.main() (19认同)
  • 为了可视化cProfile转储,RunSnakeRun自2011年以来尚未更新,并且不支持python3.您应该使用[snakeviz](https://jiffyclub.github.io/snakeviz/)代替 (12认同)
  • @NeilG即使对于python 3,[**`cprofile`仍然被推荐**](https://docs.python.org/3.4/library/profile.html)超过`profile`. (11认同)
  • 不幸的是,你无法对总时间或累计时间进行排序,这是IMO的一个主要缺陷. (7认同)
  • 另请阅读python文档[here](http://docs.python.org/2/library/profile.html)这是非常好的 (4认同)
  • 我通常会发现cumtime是您真正在意的(易于优化),以便于使用:python -m cProfile -s cumtime pyname.py (2认同)

gak*_*gak 400

前一段时间我发了pycallgraph一个从Python代码生成可视化的东西.编辑:我已经更新了示例以使用3.3,这是撰写本文时的最新版本.

pip install pycallgraph安装GraphViz之后,您可以从命令行运行它:

pycallgraph graphviz -- ./mypythonscript.py
Run Code Online (Sandbox Code Playgroud)

或者,您可以分析代码的特定部分:

from pycallgraph import PyCallGraph
from pycallgraph.output import GraphvizOutput

with PyCallGraph(output=GraphvizOutput()):
    code_to_profile()
Run Code Online (Sandbox Code Playgroud)

这些中的任何一个都将生成pycallgraph.png类似于下图的文件:

在此输入图像描述

  • 你根据通话量着色吗?如果是这样,您应该根据时间进行着色,因为具有最多呼叫的功能并不总是花费最多时间的功能. (42认同)
  • @red您可以根据需要自定义颜色,甚至可以为每次测量独立定制颜色.例如,红色表示呼叫,蓝色表示时间,绿色表示内存使用. (19认同)
  • 我更新了这一点,提到你需要安装GraphViz,以便按照描述的方式工作.在Ubuntu上,这只是"sudo apt-get install graphviz". (3认同)
  • [github页面](https://github.com/gak/pycallgraph)指出该项目已被放弃......:( (3认同)
  • 得到此错误`回溯(最近一次调用最后一次):/ pycallgraph.py",第90行,在生成output.done()文件"/net_downloaded/pycallgraph-develop/pycallgraph/output/graphviz.py",第94行, done source = self.generate()文件"/net_downloaded/pycallgraph-develop/pycallgraph/output/graphviz.py",第143行,生成indent_join.join(self.generate_attributes()),文件"/ net_downloaded/pycallgraph-develop /pycallgraph/output/graphviz.py",第169行,在generate_attributes部分,self.attrs_from_dict(attrs),ValueError:零长度字段名称格式" (2认同)
  • 这需要一些工作来安装这里是3个步骤来帮助.1.通过pip安装,2.通过exe安装GraphViz 3.将路径变量设置为GraphViz目录4.找出如何修复所有其他错误.5.找出它保存png文件的位置? (2认同)

Joe*_*haw 191

值得指出的是,使用探查器仅在主线程上工作(默认情况下),如果您使用它们,则不会从其他线程获取任何信息.这可能是一个问题,因为它在分析器文档中完全没有提及.

如果您还想要分析线程,您将需要查看文档中的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,))
Run Code Online (Sandbox Code Playgroud)

并使用ProfiledThread该类而不是标准类.它可能会给你更多的灵活性,但我不确定它是否值得,特别是如果你使用不使用你的类的第三方代码.

  • 用profiler.enable()和profiler.disable()包装代码似乎也运行得很好.这基本上就是runcall所做的,并且它不会强制执行任何数量的参数或类似的事情. (9认同)

bre*_*yne 140

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>
Run Code Online (Sandbox Code Playgroud)

或提交:

python -m cProfile -o output.file mine.py <args>
Run Code Online (Sandbox Code Playgroud)

PS>如果您使用的是Ubuntu,请确保安装python-profile

sudo apt-get install python-profiler 
Run Code Online (Sandbox Code Playgroud)

如果输出到文件,则可以使用以下工具获得良好的可视化效果

PyCallGraph:一个创建调用图形图像的工具
安装:

 sudo pip install pycallgraph
Run Code Online (Sandbox Code Playgroud)

跑:

 pycallgraph mine.py args
Run Code Online (Sandbox Code Playgroud)

视图:

 gimp pycallgraph.png
Run Code Online (Sandbox Code Playgroud)

你可以使用你喜欢的任何东西来查看png文件,我使用gimp
不幸的是我常常得到

dot:图形对于cairo-renderer位图来说太大了.按比例缩小0.257079以适应

这使我的图像非常小.所以我通常创建svg文件:

pycallgraph -f svg -o pycallgraph.svg mine.py <args>
Run Code Online (Sandbox Code Playgroud)

PS>确保安装graphviz(提供点程序):

sudo pip install graphviz
Run Code Online (Sandbox Code Playgroud)

通过@maxy/@quodlibetor使用gprof2dot替代绘图:

sudo pip install gprof2dot
python -m cProfile -o profile.pstats mine.py
gprof2dot -f pstats profile.pstats | dot -Tsvg -o mine.svg
Run Code Online (Sandbox Code Playgroud)

  • [gprof2dot](http://code.google.com/p/jrfonseca/wiki/Gprof2Dot)也可以执行这些图表.我认为输出更好一些([示例](http://maxy.homeip.net/misc/profile_tiny_straight_line_preview.png)). (11认同)
  • 如果您使用OSX,还需要graphviz (2认同)

quo*_*tor 130

@Maxy对这个答案的评论帮助我足够了,我认为它应该得到自己的答案:我已经有了cProfile生成的.pstats文件,我不想用pycallgraph重新运行,所以我使用了gprof2dot,并且很漂亮svgs:

$ 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
Run Code Online (Sandbox Code Playgroud)

和BLAM!

它使用dot(与pycallgraph使用的相同),因此输出看起来相似.我得到的印象是gprof2dot丢失的信息较少:

gprof2dot示例输出

  • 诀窍是要记住ln和cp具有相同的参数顺序 - 将其视为'将file1复制到file2或dir2,但是建立一个链接' (6认同)
  • 很好的方法,效果很好,因为您可以在 Chrome 等中查看 SVG 并放大/缩小它。第三行有错别字,应该是: ln -s ``pwd``/gprof2dot/gprof2dot.py $HOME/bin(或者在大多数 shell 中使用 ln -s $PWD/gprof2dot/gprof2dot.py ~/bin - 重音符号是作为第一个版本中的格式)。 (2认同)
  • 啊,好点.我几乎每次都得到`ln`的论证 - 错误. (2认同)

zax*_*liu 66

在研究这个主题时,我遇到了一个名为SnakeViz的方便工具.SnakeViz是一个基于Web的分析可视化工具.它非常易于安装和使用.我使用它的常用方法是生成一个stat文件,%prun然后在SnakeViz中进行分析.

使用的主要技术是如下所示的Sunburst图表,其中函数调用的层次结构被安排为以角度宽度编码的弧和时间信息的层.

最好的是你可以与图表互动.例如,要放大一个,可以单击一个圆弧,并且圆弧及其后代将被放大为新的旭日形状以显示更​​多细节.

在此输入图像描述

  • [CodeCabbie 的答案](/sf/answers/3442164771/) 包括(简短的)安装说明,并展示了如何(轻松)使用 SnakeViz。 (3认同)

Fed*_*ico 49

我认为这cProfile对于分析非常有用,同时kcachegrind对于可视化结果非常有用.该pyprof2calltree之间在处理文件转换.

python -m cProfile -o script.profile script.py
pyprof2calltree -i script.profile -o script.calltree
kcachegrind script.calltree
Run Code Online (Sandbox Code Playgroud)

要安装所需的工具(至少在Ubuntu上):

apt-get install kcachegrind
pip install pyprof2calltree
Run Code Online (Sandbox Code Playgroud)

结果:

结果截图

  • Mac用户安装`brew install qcachegrind`并在描述中将每个`kcachegrind`替换为`qcachegrind`以便成功进行性能分析。 (9认同)
  • 在此处列出的一堆解决方案中:这个解决方案最适合处理大型配置文件数据。`gprof2dot` 不是交互式的,并且没有总体 CPU 时间(只有相对百分比)`tuna` 和 `snakeviz` 在较大的配置文件上死亡。`pycallgraph` 已存档,不再维护 (2认同)
  • @YonatanSimson你可能在docker容器中运行`kcachegrind`,默认情况下它不与主机共享IPC。解决此问题的另一种方法是使用“--ipc=host”运行 docker 容器。 (2认同)

Pet*_*ete 41

另外值得一提的是GUI cProfile转储查看器RunSnakeRun.它允许您进行排序和选择,从而放大程序的相关部分.图中矩形的大小与所花费的时间成比例.如果将鼠标悬停在矩形上,则会突出显示该表中的调用以及地图上的任何位置.双击矩形时,它会放大该部分.它将显示谁调用该部分以及该部分调用的内容.

描述性信息非常有用.它显示了该位的代码,在处理内置库调用时可能会有所帮助.它告诉您查找代码的文件和行.

也想指出OP说'剖析',但看起来他的意思是"时机".请记住,在分析时程序运行速度会变慢.

在此输入图像描述


Cod*_*bie 41

找到所有时间的最简单,最快捷的方式.

1. pip install snakeviz

2. python -m cProfile -o temp.dat <PROGRAM>.py

3. snakeviz temp.dat
Run Code Online (Sandbox Code Playgroud)

在浏览器中绘制饼图.最大的一块是问题功能.非常简单.


Ian*_*ore 33

一个很好的分析模块是line_profiler(使用脚本kernprof.py调用).它可以在这里下载.

我的理解是cProfile只提供有关每个函数花费的总时间的信息.因此,各行代码都没有定时.这是科学计算中的一个问题,因为通常一条线可能需要花费很多时间.另外,正如我记得的那样,cProfile没有抓住我在numpy.dot上花费的时间.


Ben*_*enC 32

pprofile

line_profiler(已在此处展示)也受到启发 pprofile,其描述如下:

线粒度,线程感知确定性和统计纯python剖析器

它提供了线粒度line_profiler,纯Python,可以用作独立命令或模块,甚至可以生成可以轻松分析的callgrind格式文件[k|q]cachegrind.

vprof

还有vprof,一个Python包描述为:

[...]为各种Python程序特性(如运行时和内存使用情况)提供丰富的交互式可视化.

热图


Pho*_*x87 23

使用像austin这样的统计分析器,不需要任何仪器,这意味着您只需使用以下命令即可从 Python 应用程序中获取分析数据

austin python3 my_script.py
Run Code Online (Sandbox Code Playgroud)

原始输出不是很有用,但您可以将其通过管道传输到Flamegraph.pl 以获得该数据的火焰图表示形式,该表示形式可以详细说明时间(以实时微秒为单位测量)的花费情况。

austin python3 my_script.py | flamegraph.pl > my_script_profile.svg
Run Code Online (Sandbox Code Playgroud)

或者,您还可以使用 Web 应用程序Speedscope.app快速可视化所收集的样本。如果您安装了pprof,您还可以获取austin-python(例如pipx install austin-python)并使用austin2pprof转换为 pprof 格式。

但是,如果您安装了 VS Code,则可以使用Austin 扩展来获得更具交互性的体验,包括源代码热图、顶级函数和收集的调用堆栈

Austin VS Code 扩展

如果您更愿意使用终端,也可以使用TUI,它也有实时图形模式:

奥斯汀 TUI 图形模式


Nic*_*mer 20

我最近创建了用于可视化Python运行时和导入配置文件的金枪鱼 ; 这在这里可能会有所帮助.

在此输入图像描述

安装时

pip3 install tuna
Run Code Online (Sandbox Code Playgroud)

创建运行时配置文件

python -mcProfile -o program.prof yourfile.py
Run Code Online (Sandbox Code Playgroud)

或导入配置文件(需要Python 3.7+)

python -X importprofile yourfile.py 2> import.log
Run Code Online (Sandbox Code Playgroud)

然后只需在文件上运行金枪鱼

tuna program.prof
Run Code Online (Sandbox Code Playgroud)


Fra*_*ois 15

仅终端(也是最简单的)解决方案,以防所有那些花哨的 UI 无法安装或运行:完全
忽略cProfile并将其替换为pyinstrument,这将在执行后立即收集并显示调用树。

安装:

$ pip install pyinstrument
Run Code Online (Sandbox Code Playgroud)

配置文件和显示结果:

$ python -m pyinstrument ./prog.py
Run Code Online (Sandbox Code Playgroud)

适用于 python2 和 3。

[编辑] API 的文档,仅用于分析代码的一部分,可以在这里找到。

  • 谢谢你,我认为你的答案应该更高:) (3认同)

Dav*_*šek 13

有很多很棒的答案,但他们要么使用命令行,要么使用一些外部程序来分析和/或排序结果.

我真的错过了一些我可以在我的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)
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅文档或其他答案.


Pyp*_*ros 12

继乔·肖的关于多线程代码没有按预期工作的答案,我盘算了一下,runcall在CPROFILE方法仅是在做self.enable()self.disable()呼叫周围的异形函数调用,所以你可以简单地做自己,有你想要的任何代码之间用对现有代码的干扰最小.

  • 优秀小费!快速查看`cprofile.py`的源代码,可以看出_exactly_是什么`runcall()`.更具体的是,在用`prof = cprofile.Profile()`创建一个Profile实例后,立即调用`prof.disable()`,然后添加`prof.enable()`和`prof.disable()`调用围绕您想要分析的代码部分. (3认同)

Wal*_*ter 10

在Virtaal的源代码中,有一个非常有用的类和装饰器,可以很容易地进行分析(甚至对于特定的方法/函数).然后可以在KCacheGrind中非常舒适地查看输出.


Dat*_*eek 9

cProfile非常适合快速分析,但大部分时间它都以错误结束.函数runctx通过正确初始化环境和变量来解决这个问题,希望它对某些人有用:

import cProfile
cProfile.runctx('foo()', None, locals())
Run Code Online (Sandbox Code Playgroud)


Ali*_*Ali 9

我刚刚开发了自己的分析器,灵感来自 pypref_time:

\n

https://github.com/modaresimr/auto_profiler

\n

更新版本2

\n

安装:

\n
pip install auto_profiler\n
Run Code Online (Sandbox Code Playgroud)\n

快速开始:

\n
from auto_profiler import Profiler\n\nwith Profiler():\n    your_function()\n
Run Code Online (Sandbox Code Playgroud)\n

在Jupyter中使用,让您实时查看经过的时间

\n

jupyter 中自动分析器的实时视图

\n

更新版本1

\n

通过添加装饰器,它将显示一个耗时函数的树

\n

@Profiler(depth=4)

\n
Install by: pip install auto_profiler\n
Run Code Online (Sandbox Code Playgroud)\n

例子

\n
pip install auto_profiler\n
Run Code Online (Sandbox Code Playgroud)\n

示例输出

\n
\nTime   [Hits * PerHit] Function name [Called from] [function location]\n-----------------------------------------------------------------------\n8.974s [1 * 8.974]  main  [auto-profiler/profiler.py:267]  [/test/t2.py:30]\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 5.954s [5 * 1.191]  f1  [/test/t2.py:34]  [/test/t2.py:14]\n\xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 5.954s [5 * 1.191]  mysleep  [/test/t2.py:15]  [/test/t2.py:17]\n\xe2\x94\x82       \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 5.954s [5 * 1.191]  <time.sleep>\n|\n|\n|   # The rest is for the example recursive function call fact\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 3.020s [1 * 3.020]  fact  [/test/t2.py:36]  [/test/t2.py:20]\n    \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 0.849s [1 * 0.849]  f1  [/test/t2.py:21]  [/test/t2.py:14]\n    \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 0.849s [1 * 0.849]  mysleep  [/test/t2.py:15]  [/test/t2.py:17]\n    \xe2\x94\x82       \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 0.849s [1 * 0.849]  <time.sleep>\n    \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 2.171s [1 * 2.171]  fact  [/test/t2.py:24]  [/test/t2.py:20]\n        \xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 1.552s [1 * 1.552]  f1  [/test/t2.py:21]  [/test/t2.py:14]\n        \xe2\x94\x82   \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 1.552s [1 * 1.552]  mysleep  [/test/t2.py:15]  [/test/t2.py:17]\n        \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 0.619s [1 * 0.619]  fact  [/test/t2.py:24]  [/test/t2.py:20]\n            \xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 0.619s [1 * 0.619]  f1  [/test/t2.py:21]  [/test/t2.py:14]\n
Run Code Online (Sandbox Code Playgroud)\n


Mr.*_*itt 6

我的方法是使用yappi(https://code.google.com/p/yappi/).它与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 = '\n'
    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) + "\t" + str(
            round(stat[2], 2)).ljust(8 - len(str(stat[2]))) + "\t" + str(round(stat[3], 2)) + "\n"

    log.log(1000, "\nname" + ''.ljust(maxNameLen - 4) + " ncall \tttot \ttsub")
    log.log(1000, statPrint)
Run Code Online (Sandbox Code Playgroud)

然后,当您的程序工作时,您可以随时通过调用startProfilerRPC方法启动探查器并通过调用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:\Python27\lib\sched.py.run:80                                                                                                           22        0.11    0.05
M:\02_documents\_repos\09_aheadRepos\apps\ahdModbusSrv\pyAheadRpcSrv\xmlRpc.py.iterFnc:293                                                22        0.11    0.0
M:\02_documents\_repos\09_aheadRepos\apps\ahdModbusSrv\serverMain.py.makeIteration:515                                                    22        0.11    0.0
M:\02_documents\_repos\09_aheadRepos\apps\ahdModbusSrv\pyAheadRpcSrv\PicklingXMLRPC.py._dispatch:66                                       1         0.0     0.0
C:\Python27\lib\BaseHTTPServer.py.date_time_string:464                                                                                    1         0.0     0.0
c:\users\zasiec~1\appdata\local\temp\easy_install-hwcsr1\psutil-1.1.2-py2.7-win32.egg.tmp\psutil\_psmswindows.py._get_raw_meminfo:243     4         0.0     0.0
C:\Python27\lib\SimpleXMLRPCServer.py.decode_request_content:537                                                                          1         0.0     0.0
c:\users\zasiec~1\appdata\local\temp\easy_install-hwcsr1\psutil-1.1.2-py2.7-win32.egg.tmp\psutil\_psmswindows.py.get_system_cpu_times:148 4         0.0     0.0
<string>.__new__:8                                                                                                                        220       0.0     0.0
C:\Python27\lib\socket.py.close:276                                                                                                       4         0.0     0.0
C:\Python27\lib\threading.py.__init__:558                                                                                                 1         0.0     0.0
<string>.__new__:8                                                                                                                        4         0.0     0.0
C:\Python27\lib\threading.py.notify:372                                                                                                   1         0.0     0.0
C:\Python27\lib\rfc822.py.getheader:285                                                                                                   4         0.0     0.0
C:\Python27\lib\BaseHTTPServer.py.handle_one_request:301                                                                                  1         0.0     0.0
C:\Python27\lib\xmlrpclib.py.end:816                                                                                                      3         0.0     0.0
C:\Python27\lib\SimpleXMLRPCServer.py.do_POST:467                                                                                         1         0.0     0.0
C:\Python27\lib\SimpleXMLRPCServer.py.is_rpc_path_valid:460                                                                               1         0.0     0.0
C:\Python27\lib\SocketServer.py.close_request:475                                                                                         1         0.0     0.0
c:\users\zasiec~1\appdata\local\temp\easy_install-hwcsr1\psutil-1.1.2-py2.7-win32.egg.tmp\psutil\__init__.py.cpu_times:1066               4         0.0     0.0 
Run Code Online (Sandbox Code Playgroud)

它对于短脚本可能不是很有用,但有助于优化服务器类型的过程,特别是考虑到printProfiler可以多次调用该方法来分析和比较例如不同的程序使用场景.


Fab*_*zny 6

PyVmMonitor 是一个在 Python 中处理分析的新工具:http://www.pyvmonitor.com/

它有一些独特的功能,例如

  • 将探查器附加到正在运行的 (CPython) 程序
  • 通过 Yappi 集成进行按需分析
  • 在不同的机器上配置文件
  • 多进程支持(多处理、django...)
  • 实时采样/CPU 视图(带时间范围选择)
  • 通过 cProfile/profile 集成进行确定性分析
  • 分析现有 PStats 结果
  • 打开DOT文件
  • 编程式 API 访问
  • 按方法或系列对样品进行分组
  • PyDev 集成
  • PyCharm 集成

注意:它是商业的,但免费开源。


Mat*_*ijn 6

gprof2dot_magic

用于gprof2dot在 JupyterLab 或 Jupyter Notebook 中将任何 Python 语句配置为 DOT 图的魔术函数。

在此处输入图片说明

GitHub 存储库:https : //github.com/mattijn/gprof2dot_magic

安装

确保你有 Python 包gprof2dot_magic

pip install gprof2dot_magic
Run Code Online (Sandbox Code Playgroud)

它的依赖项gprof2dotgraphviz将被安装

用法

要启用魔法功能,首先加载gprof2dot_magic模块

%load_ext gprof2dot_magic
Run Code Online (Sandbox Code Playgroud)

然后将任何 line 语句配置为 DOT 图,如下所示:

%gprof2dot print('hello world')
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明


mos*_*evi 6

如果要制作累积分析器,则意味着连续运行该函数几次,并观察结果的总和。

您可以使用以下cumulative_profiler装饰器:

它是特定于python> = 3.6的python,但是您可以删除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
Run Code Online (Sandbox Code Playgroud)

分析功能 baz

import time

@cumulative_profiler
def baz():
    time.sleep(1)
    time.sleep(2)
    return 1

baz()
Run Code Online (Sandbox Code Playgroud)

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}
Run Code Online (Sandbox Code Playgroud)

指定次数

@cumulative_profiler(3)
def baz():
    ...
Run Code Online (Sandbox Code Playgroud)


Adi*_*aik 6

用于在 IPython 笔记本上快速获取个人资料统计信息。可以将line_profilermemory_profiler直接嵌入到他们的笔记本中。

另一个有用的包是Pympler。它是一个强大的分析包,能够跟踪类、对象、函数、内存泄漏等。下面的示例,附上文档。

得到它!

!pip install line_profiler
!pip install memory_profiler
!pip install pympler
Run Code Online (Sandbox Code Playgroud)

加载它!

%load_ext line_profiler
%load_ext memory_profiler
Run Code Online (Sandbox Code Playgroud)

用它!


%时间

%time print('Outputs CPU time,Wall Clock time') 
#CPU times: user 2 µs, sys: 0 ns, total: 2 µs Wall time: 5.96 µs
Run Code Online (Sandbox Code Playgroud)

给出:

  • CPU 次数:CPU 级执行时间
  • sys times:系统级执行时间
  • 总计:CPU时间+系统时间
  • 挂钟时间:挂钟时间

%timeit

%timeit -r 7 -n 1000 print('Outputs execution time of the snippet') 
#1000 loops, best of 7: 7.46 ns per loop
Run Code Online (Sandbox Code Playgroud)
  • 在循环 (n) 次中给出给定运行次数 (r) 中的最佳时间。
  • 输出有关系统缓存的详细信息:
    • 当代码片段被多次执行时,系统会缓存一些操作并且不会再次执行它们,这可能会妨碍配置文件报告的准确性。

%修剪

%prun -s cumulative 'Code to profile' 
Run Code Online (Sandbox Code Playgroud)

给出:

  • 函数调用次数(ncalls)
  • 每个函数调用都有条目(不同)
  • 每次通话所用时间(每次通话)
  • 直到该函数调用的时间(cumtime)
  • 调用的函数/模块的名称等...

累积资料


% 记住

%memit 'Code to profile'
#peak memory: 199.45 MiB, increment: 0.00 MiB
Run Code Online (Sandbox Code Playgroud)

给出:

  • 内存使用情况

%l修剪

#Example function
def fun():
  for i in range(10):
    print(i)

#Usage: %lprun <name_of_the_function> function
%lprun -f fun fun()
Run Code Online (Sandbox Code Playgroud)

给出:

  • 行明智的统计

线型


sys.getsizeof

sys.getsizeof('code to profile')
# 64 bytes
Run Code Online (Sandbox Code Playgroud)

以字节为单位返回对象的大小。


来自 pympler 的 asizeof()

from pympler import asizeof
obj = [1,2,("hey","ha"),3]
print(asizeof.asizeof(obj,stats=4))

Run Code Online (Sandbox Code Playgroud)

pympler.asizeof 可用于调查某些 Python 对象消耗了多少内存。与 sys.getsizeof 相比,asizeof 递归地调整对象的大小

pympler.asizeof


来自pympler的跟踪器

from pympler import tracker
tr = tracker.SummaryTracker()
def fun():
  li = [1,2,3]
  di = {"ha":"haha","duh":"Umm"}
fun()
tr.print_diff()
Run Code Online (Sandbox Code Playgroud)

跟踪函数的生命周期。

跟踪器输出

Pympler 包包含大量用于分析代码的高效实用函数。所有这些都不能在这里涵盖。有关详细配置文件实现,请参阅随附的文档。

Pympler文档


use*_*489 6

Scalene 是一个新的 Python 分析器,涵盖许多用例并且对性能影响最小:

https://github.com/plasma-umass/scalene

它可以非常精细地分析 CPU、GPU 和内存利用率。它还特别支持多线程/并行 python 代码。


小智 5

要添加到/sf/answers/40763621/

我编写了这个模块,它允许您使用 cProfile 并轻松查看其输出。更多信息请参见: https: //github.com/ymichael/cprofilev

$ python -m cprofilev /your/python/program
# Go to http://localhost:4000 to view collected statistics.
Run Code Online (Sandbox Code Playgroud)

另请参阅: http: //ymichael.com/2014/03/08/profiling-python-with-cprofile.html,了解如何理解收集的统计数据。


小智 5

这取决于您希望从分析中看到什么。简单的时间度量可以通过 (bash) 给出。

time python python_prog.py
Run Code Online (Sandbox Code Playgroud)

甚至“/usr/bin/time”也可以通过使用“--verbose”标志输出详细的指标。

要检查每个函数给出的时间指标并更好地了解函数花费了多少时间,您可以使用 python 中内置的 cProfile。

进入更详细的指标(例如性能),时间并不是唯一的指标。您可以担心内存、线程等。
分析选项:
1. line_profiler是另一个分析器,通常用于逐行查找计时指标。
2. memory_profiler是一个分析内存使用情况的工具。
3. heapy(来自 Guppy 项目)分析堆中对象的使用方式。

这些是我倾向于使用的一些常见的。但如果您想了解更多信息,请尝试阅读这本书。 这是一本关于从性能开始的非常好的书。您可以转到有关使用 Cython 和 JIT(即时)编译的 python 的高级主题。


jus*_*usx 5

最近我为 PyCharm 创建了一个插件,您可以使用它轻松分析和可视化line_profilerPyCharm 编辑器中的结果。

line_profiler 在其他答案中也提到过,它是一个很好的工具,可以准确分析 python 解释器在某些行中花费了多少时间。

我创建的 PyCharm 插件可以在这里找到:https : //plugins.jetbrains.com/plugin/16536-line-profiler

它需要在你的 python 环境中调用一个帮助包,line-profiler-pycharm它可以用 pip 或插件本身安装。

在 PyCharm 中安装插件后:

  1. 任何装饰功能要与剖析line_profiler_pycharm.profile装饰
  2. 使用“Profile Lines”跑步者跑步

结果截图: Line Profiler Pycharm 结果