如何分析 Python 脚本?

2024-11-18 08:41:00
admin
原创
13
摘要:问题描述:欧拉计划和其他编程竞赛通常都有最大运行时间,或者人们会吹嘘他们的特定解决方案运行得有多快。对于 Python,有时方法有些笨拙 - 即添加计时代码__main__。有什么好方法可以分析 Python 程序运行的时间?解决方案 1:Python 包含一个名为 的分析器cProfile。它不仅提供总运行...

问题描述:

欧拉计划和其他编程竞赛通常都有最大运行时间,或者人们会吹嘘他们的特定解决方案运行得有多快。对于 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 丢失的信息较少:

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 扩展获得更具交互性的体验,其中包含源代码热图、顶级函数和收集的调用堆栈

Austin VS Code 扩展

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

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 关于多线程代码无法按预期工作的回答,我发现runcallcProfile 中的方法只是在执行self.enable()self.disable()调用被分析的函数调用,因此您可以自己简单地执行此操作,并在两者之间添加您想要的任何代码,同时尽量减少对现有代码的干扰。

解决方案 17:

用于在 IPython 笔记本上快速获取配置文件统计信息。可以将line_profilermemory_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.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中安装插件后:

  1. line_profiler_pycharm.profile使用装饰器来装饰你想要分析的任何函数

  2. 与“Profile Lines”跑步者一起奔跑

结果截图:
线路分析器 Pycharm 结果

解决方案 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 中使用,可以实时查看运行时间

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

它的依赖项gprof2dotgraphviz将被安装

用法

要启用魔法功能,首先加载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)

然后,当您的程序工作时,您可以随时通过调用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:Python27libsched.py.run:80                                                                                                           22        0.11    0.05
M:_documents_repos9_aheadReposappsahdModbusSrvpyAheadRpcSrvxmlRpc.py.iterFnc:293                                                22        0.11    0.0
M:_documents_repos9_aheadReposappsahdModbusSrvserverMain.py.makeIteration:515                                                    22        0.11    0.0
M:_documents_repos9_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。

进入更详细的指标(如性能),时间并不是唯一的指标。您可以关注内存、线程等。

分析选项:

  1. 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()

另请参阅https://stackoverflow.com/a/10333592/320036

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用