首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何分析我的代码?

如何分析我的代码?
EN

Stack Overflow用户
提问于 2010-06-15 21:27:07
回答 3查看 14.5K关注 0票数 22

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

我已经看过了文档,但由于没有给出任何例子,我无法从中得到任何东西。

我有一个很大的代码,它占用了这么多的时间,因此我想要剖析并提高它的速度。我还没有写我的代码在方法中,有一些中间的,但不是完全的。我的代码中没有任何main。我想知道如何使用分析。我正在寻找一些关于如何分析的例子或样本代码。

我试过啦,也就是在我的代码顶端加了两行:

代码语言:javascript
复制
import psyco
psyco.full()

是这样的吗?它没有显示出任何改进。任何其他加速的方式,请提出建议。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-06-18 16:11:11

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

但是,如果不将代码分成cProfile不会给您提供特别丰富信息的方法,您就会发现

取而代之的是,你可能想尝试一下另一位发帖人在这里所说的蒙特卡洛剖析。引用another answer的话

如果你很匆忙,并且你可以在调试器下手动中断你的程序,而它主观上很慢,那么有一个简单的方法可以找到性能问题。

只需停止它几次,每次查看调用堆栈。如果有一些代码浪费了一定百分比的时间,20%或50%或者其他什么,那就是你在每个样本上捕捉到它的概率,,所以这大致是你看到它的样本的百分比。不需要有经验的猜测。如果你确实有一个问题是什么的猜测,这将证明或反驳它。

您可能会遇到不同大小的多个性能问题。如果你清理掉其中的任何一个,剩下的将占据更大的比例,并且在后续的传递中更容易被发现。

警告:程序员往往对这种技术持怀疑态度,除非他们自己使用过它。他们会说分析器会给你这些信息,但只有在他们对整个调用栈进行采样的情况下,这才是真的。调用图不会给你提供相同的信息,因为1)它们不会在指令级别进行汇总,2)它们在存在递归的情况下会给出令人困惑的汇总。他们还会说,它只适用于玩具程序,而实际上它适用于任何程序,而且它似乎在更大的程序上工作得更好,因为他们倾向于有更多的问题来寻找重点。

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

最棒的是,这在Python中是非常容易做到的。只需在解释器中运行Python脚本,按Control-C组合键,记下回溯并重复多次。

票数 66
EN

Stack Overflow用户

发布于 2012-03-07 08:51:00

编辑:

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

使用cProfile进行性能分析

这是我前段时间写的一篇关于使用cProfile进行性能分析的文章,并提供了一些图形帮助。

cProfile是目前使用最多的python分析器之一,虽然功能非常强大,但标准文本输出有些平淡无奇。在这里,我将向您展示如何以一种更简单的方式在应用程序上使用cProfile。

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

分析模块

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

代码语言:javascript
复制
python -m cProfile -o output_filename.pstats path/to/script arg1 arg2

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

有一些lots of ways可以读取输出文件中的数据,但为了这篇文章的目的,让我们不要担心这些,而是专注于获得图形可视化。

从内部分析

有时,您不想分析整个模块,只需要几行代码。

要做到这一点,你必须向你的模块添加一些代码。

首先:

代码语言:javascript
复制
import cProfile

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

代码语言:javascript
复制
cProfile.runctx('Your code here', globals(), locals(), 'output_file')

例如,下面是分析之前和之后的测试:

代码语言:javascript
复制
import unittest

class Test(unittest.TestCase):

    def testSomething(self):
        self.DoSomethingIDontCareAbout()

        param = 'whatever'
        self.RunFunctionIThinkIsSlow(param)

        self.AssertSomeStuff() # This is after all, a test

之后:

代码语言:javascript
复制
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

将pstats文件转换为图形

要将分析文件转换为图形,您将需要一些东西:

  • gprof2dot:此模块将您的输出转换为图形descriptions.
  • GraphViz:的标准文件格式文件。它将您的文件转换为图像。

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

代码语言:javascript
复制
python gprof2dot -f pstats myProfileFile | dot -Tpng -o image_output.png

您可能必须为gprof2dot和/或使用完整的路径,或者可以将它们添加到path环境变量中。

完成所有这些之后,您应该有一个类似于以下内容的图像:

  • 较热的颜色(红色、橙色、黄色)表示占用总运行时间的函数比较冷的颜色(绿色、蓝色)多
  • 在每个节点上,您可以查看该函数使用的总运行时间的百分比以及节点之间的called.
  • Arrows次数指示哪个函数调用了其他函数,这样的箭头还具有一个标题,指示通过该函数的运行时间百分比。

注意:百分比并不总是等于100%,特别是在引用C++代码的代码部分,这不会被分析。cProfile也无法确定从"eval“语句内部调用了什么,因此您可能会在图形中看到一些跳跃。

票数 19
EN

Stack Overflow用户

发布于 2010-06-18 15:23:15

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

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3045556

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档