【问题标题】:How to profile my code?如何分析我的代码?
【发布时间】:2011-03-03 23:59:03
【问题描述】:

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

我浏览了文档,但由于没有给出示例,我无法从中得到任何东西。

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

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

import psyco
psyco.full()

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

【问题讨论】:

  • "但无法成功" 没有任何意义。提供您使用的具体、具体的代码和您遇到的错误。请具体
  • 请哪位用过profiler的人帮帮我吧!!
  • psyco 并不总是意味着提高性能。如果您的应用程序所做的只是等待 IO,那么更快的执行不会有任何影响。您需要先进行分析,然后再进行优化。

标签: python profiling


【解决方案1】:

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

【讨论】:

  • 你能举一个使用cmd的例子吗..我需要导入任何东西吗..是python 2.6的cprofile部分
  • 发布的链接指向一个叫做“即时用户手册”的东西,这实际上是一个很好的起点。它还包含示例。
  • 我链接了文档,你可以在那里找到示例命令python -m cProfile myscript.py
【解决方案2】:

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

您会发现如果不将代码分离成 cProfile 不会为您提供特别丰富信息的方法

相反,您可能想尝试此处另一位发帖人所称的 Monte Carlo Profiling。引用another answer:

如果你赶时间,你可以 手动中断您的程序 调试器,而它正在 主观上慢,有一个简单的 发现性能问题的方法。

暂停几次,每次 有时间看看调用栈。 如果有 是一些浪费一些代码 时间百分比,20% 或 50% 或 无论如何,这是概率 你会在每个动作中抓住它 示例。 所以这大致是 样本百分比 会看到的。没有受过教育的 需要猜测。如果你有一个 猜猜是什么问题,这个 将证明或反驳它。

您可能有多个表现 大小不同的问题。如果你 清除其中任何一个, 其余的将需要更大的 百分比,并且更容易发现 随后的传球。

警告:程序员往往 对这种技术持怀疑态度,除非 他们自己用过。他们将 说分析器给你这个 信息,但只有在 他们对整个调用堆栈进行采样。 调用图不一样 信息,因为 1) 他们没有 在教学层面总结, 2)他们给出了令人困惑的总结 在递归的情况下。他们 还会说它只适用于玩具 程序,当它实际运行时 任何程序,它似乎工作 在更大的程序上更好,因为 他们往往有更多的问题 找到[强调]。

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

最好的一点是,这在 Python 中非常容易做到。只需在解释器中运行您的 Python 脚本,按 [Control-C],记下回溯并重复多次。

【讨论】:

  • 我觉得说这是“不正统”很奇怪;我的意思是,这就是诸如 gprof 之类的分析工具的实际工作方式。来自 gprof 手册:“分析还涉及在程序运行时观察程序,并保持程序计数器不时发生的位置的直方图。”和“gprof 为您提供的运行时间数据是基于抽样过程的,因此它们可能存在统计上的不准确性。”。
  • 我们使用同样的技术来分析嵌入式 C 应用程序。
  • [笑话] “我的代码似乎把所有时间都花在了 KeyboardInterrupt 处理程序中。”
  • 这也是 plop github.com/bdarnell/plop profiler 正在使用的技术。
  • 此方法的一个缺点是 GIL(全局解释器锁)意味着如果您使用多个线程,这可能会严重失败。基本上,信号仅由主线程处理,这会阻止 ^C 获得有用的输出。 (或为此工作)
【解决方案3】:

编辑:

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

使用 cProfile 进行分析

这是我前段时间写的一篇关于使用 cProfile 进行概要分析的文章。

cProfile 是最常用的 Python 分析器之一,虽然功能非常强大,但标准文本输出有些乏善可陈。在这里,我将向您展示如何以更简单的方式在您的应用程序中使用 cProfile。

使用 cProfile 有两种常用方法,您可以将其用作提示符中的命令来分析给定模块,也可以在代码中使用它来分析代码的特定 sn-ps。

分析模块

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

python -m cProfile -o output_filename.pstats path/to/script arg1 arg2

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

lots of ways 可以读取该输出文件上的数据,但就本文而言,我们不必担心这些,而是​​专注于获得图形可视化。

从内部分析

有时您不想分析整个模块,只分析其中的几行。

为此,您必须在模块中添加一些代码。

首先:

import cProfile

然后,您可以将任何代码段替换为以下内容:

cProfile.runctx('Your code here', globals(), locals(), 'output_file')

例如,这是一个分析前后的测试:

import unittest

class Test(unittest.TestCase):

    def testSomething(self):
        self.DoSomethingIDontCareAbout()

        param = 'whatever'
        self.RunFunctionIThinkIsSlow(param)

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

之后:

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:此模块会将您的输出转换为 dot 文件,这是一种用于图形描述的标准文件格式。
  • GraphViz:它将您的 dot 文件转换为图像。

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

python gprof2dot -f pstats myProfileFile | dot -Tpng -o image_output.png

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

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

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

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

  • 节点之间的箭头表示哪个函数调用了其他函数,并且这些箭头还有一个标题,表示运行时的百分比是多少。

注意:百分比加起来并不总是 100%,尤其是在引用 C++ 代码的代码部分上,这些代码不会被分析。 cProfile 也无法确定“eval”语句中调用的内容,因此您可能会在图表中看到一些跳跃。

【讨论】:

  • 您最初是在博客上发布此内容的吗?如果有,有链接吗?
  • @joshua.r.smith 这是一个公司内部博客,所以我猜你可以使用 stackoverflow 中的永久链接 :)
  • 这样的调用图是一个漂亮的像素的漂亮例子,它没有发现加速。他们所做的只是让您大致了解一些例程有多忙,而大多数例程并不是很忙。加速到hide in all that 非常容易。
  • 当然,由于您的帖子中解释的原因,其中可能隐藏着一些东西。我的个人经验表明,这些类型的图表仍然非常有用,并且会很快将您指向可以进行 80% 优化的地方。如果失败,请随意运行您的代码 100 次,随机中断并读取调用堆栈 :)
  • @campos.ddc:我从来不需要采集超过 20 个样本。 10 通常足以找到一些东西。我可能会遇到 10% 的问题,平均需要 20 个样本才能看到两次。但从经验上看,总有一个更大的潜伏者,一个分析器可能找不到,但检查样本肯定会。去除较大的(假设为 33%)后,现在 10% 的问题为 15%,因此只需 13 个样本(平均)即可看到两次。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-08
  • 2011-05-09
  • 2012-11-21
  • 1970-01-01
  • 2010-10-02
相关资源
最近更新 更多