如何配置我的代码?

kak*_*aki 20 python profiling

我想知道如何分析我的代码.

我已经阅读了文档,但由于没有给出任何例子,我无法从中得到任何结果.

我有一个很大的代码,它花了很多时间,因此我想分析并提高其速度.我没有在方法中编写我的代码,其间很少但不完全.我的代码中没有任何主要内容.我想知道如何使用分析.我正在寻找关于如何分析的一些示例或示例代码.

我尝试了psyco,即在我的代码顶部添加两行:

import psyco
psyco.full()
Run Code Online (Sandbox Code Playgroud)

这是正确的吗?它没有表现出任何改善.任何其他加速方式,请建议.

fma*_*ark 66

这个问题的标准答案是使用cProfile.

你会发现,如果没有将你的代码分成cProfile不会给你特别丰富的信息的方法.

相反,您可能想尝试另一张海报在这里称为Monte Carlo Profiling.引用另一个答案:

如果你赶时间并且你可以 手动中断调试器下的程序,而主观速度很慢,那么找到性能问题的方法很简单.

只需暂停几次,每次都看一下调用堆栈.如果有一些代码浪费了一定比例的时间,20%或50%或其他什么,那就是你在每个样本的行为中捕获它的概率.所以这大约是您将看到它的样本的百分比.没有必要的教育猜测.如果您确实猜到了问题所在,这将证明或反驳它.

您可能会遇到不同大小的多个性能问题.如果你清除其中任何一个,剩下的将占用更大的百分比,并且在随后的传球中更容易发现.

警告:程序员往往对这种技术持怀疑态度,除非他们自己使用它.他们会说分析器会为您提供这些信息,但只有在他们对整个调用堆栈进行采样时才会这样.调用图不会给出相同的信息,因为1)它们不在指令级别汇总,2)它们在递归的情况下给出混乱的摘要.他们还会说它只适用于玩具程序,实际上它适用于任何程序,并且它似乎在更大的程序上工作得更好,因为它们往往有更多的问题需要找到[ 强调添加 ].

这不是正统的,但我在一个项目中非常成功地使用它,在这个项目中,使用cProfile进行分析并没有给我有用的输出.

关于它的最好的事情是,在Python中这很容易做到.只需在解释器中运行Python脚本,按[Control-C],记下回溯并重复多次.

  • [笑话]"我的代码似乎把所有时间花在了KeyboardInterrupt处理程序上." (13认同)
  • 我觉得很奇怪,这是"不正统"; 我的意思是,这是严肃的gprof工具如何实际工作.从gprof手册:"分析还涉及在程序运行时观察程序,并保持程序计数器不时发生的直方图." 并且"gprof为您提供的运行时数据基于抽样过程,因此它们会受到统计不准确的影响." (8认同)
  • 我们使用相同的技术来分析嵌入式C应用程序. (2认同)

cam*_*ddc 18

编辑:

这个答案已在https://github.com/campos-ddc/cprofile_graph中实现

使用cProfile进行分析

这是我前段时间写过的关于使用cProfile进行概要分析和一些图形辅助的帖子.

cProfile是最常用的python剖析器之一,虽然非常强大,但标准文本输出有点乏味.在这里,我将向您展示如何以更简单的方式在您的应用程序中使用cProfile.

有两种常用的方法可以使用cProfile,您可以将它用作提示中的命令来分析给定的模块,或者您可以在代码中使用它来分析特定的代码片段.

分析模块

要使用cProfile分析整个模块,只需在提示中使用以下命令:

python -m cProfile -o output_filename.pstats path/to/script arg1 arg2
Run Code Online (Sandbox Code Playgroud)

这将使用给定的参数运行您的模块(它们是可选的)并将输出转储到output_filename.pstats中.

很多方法可以读取该输出文件中的数据,但是为了这篇文章的目的,让我们不要担心这些并专注于获取图形可视化.

从内部剖析

有时您不想分析整个模块,只需几行.

为此,您必须向模块添加一些代码.

首先:

import cProfile
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用以下代码替换任何代码段:

cProfile.runctx('Your code here', globals(), locals(), 'output_file')
Run Code Online (Sandbox Code Playgroud)

例如,以下是分析前后的测试:

import unittest

class Test(unittest.TestCase):

    def testSomething(self):
        self.DoSomethingIDontCareAbout()

        param = 'whatever'
        self.RunFunctionIThinkIsSlow(param)

        self.AssertSomeStuff() # This is after all, a test
Run Code Online (Sandbox Code Playgroud)

后:

import unittest
import cProfile

class Test(unittest.TestCase):

    def testSomething(self):
        self.DoSomethingIDontCareAbout()

        param = 'whatever'
        cProfile.runctx(
            'self.RunFunctionIThinkIsSlow(param)',
            globals(),
            locals(),
            'myProfilingFile.pstats'
        )

        self.AssertSomeStuff() # This is after all, a test
Run Code Online (Sandbox Code Playgroud)

将pstats文件转换为图形

要将分析文件转换为图形,您需要做以下几件事:

  • gprof2dot:此模块将您的输出转换为文件,这是图形描述的标准文件格式.
  • GraphViz:它将您的文件转换为图像.

下载gprof2dot并安装GraphViz后,在提示符中运行以下命令:

python gprof2dot -f pstats myProfileFile | dot -Tpng -o image_output.png
Run Code Online (Sandbox Code Playgroud)

您可能必须使用gprof2dot和/或dot的完整路径,或者您可以将它们添加到PATH env变量中.

在所有这些之后,你应该有一个看起来像这样的图像:

结果的例子

  • 较热的颜色(红色,橙色,黄色)表示占用总运行时间的函数比较冷的颜色(绿色,蓝色)

  • 在每个节点上,您可以看到该函数使用的总运行时间的百分比以及调用的次数.

  • 节点之间的箭头表示哪个函数称为其他函数,此类箭头还有一个标题,指示运行时通过哪个百分比.

注意:百分比总是不能总计达到100%,特别是在引用C++代码的代码部分上,这些部分不会被分析.cProfile也无法确定从"eval"语句中调用的内容,因此您可能会在图表中看到一些跳转.


Joh*_*rra 6

使用cProfile.您可以从命令行使用它并将模块作为参数传入,因此您不需要main方法.