如何分析我的代码?

发布于 2024-09-05 08:27:57 字数 311 浏览 2 评论 0原文

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

我已经阅读了文档,但由于没有给出示例,我无法从中得到任何信息。

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

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

import psyco
psyco.full()

这是正确的吗?它没有显示出任何改善。 还有什么办法可以加快速度,请指教。

I want to know how to profile my code.

I have gone through the docs, but as there were no examples given I could not get anything from it.

I have a large code and it is taking so much time, hence I want to profile and increase its speed.
I havent written my code in method, there are few in between but not completely.
I don't have any main in my code. I want to know how to use profiling.
I'm looking for some example or sample code of about how to profile.

I tried psyco, i.e just addded two lines at the top of my code:

import psyco
psyco.full()

Is this right? It did not show any improvement.
Any other way of speeding up, please suggest.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

倒数 2024-09-12 08:27:57

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

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

相反,您可能想尝试这里另一张海报所说的蒙特卡罗分析。引用另一个答案

如果你赶时间,你可以
手动中断您的程序
调试器在运行时

主观上很慢,有一个简单的
查找性能问题的方法。

只需停止几次,然后每次
有时间看一下调用堆栈。 如果有
是一些代码浪费了一些
时间百分比,20% 或 50% 或
不管怎样,这就是概率
你会在每一次的行动中发现它
样本。
这大致是
您所使用的样本的百分比
会看到它。没有受过教育的
需要猜测。如果您有
猜猜问题是什么,这个
将证明或反驳它。

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

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

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

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

The standard answer to this question is to use cProfile.

You'll find though that without having your code separated out into methods that cProfile won't give you particularly rich information.

Instead, you might like to try what another poster here calls Monte Carlo Profiling. To quote from another answer:

If you're in a hurry and you can
manually interrupt your program under
the debugger
while it's being
subjectively slow, there's a simple
way to find performance problems.

Just halt it several times, and each
time look at the call stack. If there
is some code that is wasting some
percentage of the time, 20% or 50% or
whatever, that is the probability that
you will catch it in the act on each
sample.
So that is roughly the
percentage of samples on which you
will see it. There is no educated
guesswork required. If you do have a
guess as to what the problem is, this
will prove or disprove it.

You may have multiple performance
problems of different sizes. If you
clean out any one of them, the
remaining ones will take a larger
percentage, and be easier to spot, on
subsequent passes.

Caveat: programmers tend to be
skeptical of this technique unless
they've used it themselves. They will
say that profilers give you this
information, but that is only true if
they sample the entire call stack.
Call graphs don't give you the same
information, because 1) they don't
summarize at the instruction level,
and 2) they give confusing summaries
in the presence of recursion. They
will also say it only works on toy
programs, when actually it works on
any program, and it seems to work
better on bigger programs, because
they tend to have more problems to
find [emphasis added].

It's not orthodox, but I've used it very successfully in a project where profiling using cProfile was not giving me useful output.

The best thing about it is that this is dead easy to do in Python. Simply run your Python script in the interpreter, press [Control-C], note the traceback and repeat a number of times.

旧城空念 2024-09-12 08:27:57

编辑:

此答案已在 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

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

很多方法来读取该输出文件上的数据,但目的是在这篇文章中,我们不用担心这些,而是​​专注于获得图形可视化。

从内部进行分析

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

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

首先:

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

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

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

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

完成所有这些之后,您应该得到一个看起来有点像这样的图像:

results example

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

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

  • 节点之间的箭头指示哪个函数调用了其他函数,这样的箭头还有一个标题,指示运行时的百分比是通过那里的。

    节点之间的箭头指示

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

Edit:

This answer has been implemented in https://github.com/campos-ddc/cprofile_graph

Profiling with cProfile

Here's a post I wrote some time ago on profiling with cProfile with some graphical aid.

cProfile is one of the most used python profilers out there, and although very powerful, the standard text output is somewhat lackluster. Here I'll show you how to use cProfile on your application in an easier way.

There are two common ways to use cProfile, you can use it as a command in prompt to profile a given module, or you can use it inside your code, to profile specific snippets of code.

Profiling a module

To use cProfile to profile an entire module, simply use the following command in your prompt:

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

This will run your module with the given arguments (they are optional) and dump the output in output_filename.pstats.

There are lots of ways to read the data on that output file, but for the purpose of this post, let's not worry about those and focus on getting that graphical visualization.

Profiling from inside

Sometimes you don't want to profile an entire module, just a few lines of it.

To do so, you are gonna have to add some code to your module.

First of all:

import cProfile

And then, you can replace any segment of code with the following:

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

For example, here is a test before and after profiling:

import unittest

class Test(unittest.TestCase):

    def testSomething(self):
        self.DoSomethingIDontCareAbout()

        param = 'whatever'
        self.RunFunctionIThinkIsSlow(param)

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

After:

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

Converting a pstats file to a graph

To convert your profiling file to a graph, you will need a couple of things:

  • gprof2dot: This module will convert your output into a dot file, a standard file format for graph descriptions.
  • GraphViz: It turns your dot file into an image.

After you have downloaded gprof2dot and installed GraphViz, run this command in your prompt:

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

You might have to use a complete path for gprof2dot and/or dot, or you could add them to your PATH env variable.

After all of this, you should have an image that looks kinda like this:

results example

  • Hotter colors (red, orange, yellow) indicate functions that take up more of the total runtime than colder colors (green, blue)

  • On each node, you can see what percentage of the total runtime that function used and how many times it was called.

  • Arrows between nodes indicate which function called other functions, and such arrows also have a caption indicating what percentage of the runtime came through there.

Note: percentages won't always add up to 100%, especially on code sections that reference C++ code, which won't be profiled. cProfile also won't be able to determine what's called from inside an "eval" statement, so you might see some jumps in your graph.

戈亓 2024-09-12 08:27:57

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

Use cProfile. You can use it from the command line and pass in your module as a parameter, so you don't need a main method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文