6

使用标准调试器调试性能问题几乎是没有希望的,因为细节级别太高了。其他方法是使用分析器,但它们很少给我很好的信息,尤其是当涉及 GUI 和后台线程时,因为我不知道用户是否真的在等待计算机。另一种方法是简单地使用 Control + C 并查看它在代码中停止的位置。

我真正想要的是将快进、播放、暂停和倒带功能与代码的一些视觉表现相结合。这意味着我可以将代码设置为在快进上运行,直到我将 GUI 导航到关键点。然后我将代码设置为以慢速模式运行,同时我得到一些视觉表示,正在执行哪些行(可能是代码的某种缩小视图)。例如,我可以将执行速度设置为 0.0001x。我相信我会通过这种方式获得非常好的可视化效果,无论问题是在特定模块内部,还是在模块之间的通信中。

这存在吗?我的具体需求是 Python,但我有兴趣在任何语言中看到这样的功能。

4

3 回答 3

4

“快进到关键点”功能已经存在于任何调试器中,它被称为“断点”。确实有调试器可以减慢执行速度,但这不会帮助您调试性能问题,因为它不会减慢计算机的速度。处理器、磁盘和内存仍然和以前一样慢,所发生的只是调试器在每行代码之间插入延迟。这意味着每行代码突然或多或少地花费相同的时间,这意味着它隐藏了性能问题所在的任何痕迹。

找出性能问题的唯一方法是记录在应用程序中完成的每个调用以及花费了多长时间。这就是分析器所做的。确实,使用分析器很棘手,但可能没有更好的选择。从理论上讲,您可以记录每个呼叫和每个呼叫的时间,然后通过倒带来回播放,但这会占用惊人的内存量,而且它实际上不会告诉您比分析器更多的信息(事实上,它会告诉你更少,因为它会错过某些类型的性能问题)。

您应该能够使用分析器找出需要很长时间的原因。请注意,这可能是由于某些函数调用需要很长时间,因为它们进行了大量处理,或者可能是需要很长时间的系统调用变得很慢(网络/磁盘)。或者可能是一个非常快速的调用被称为负载和负载。分析器将帮助您解决这个问题。但是,如果您可以仅在关键部分打开分析器(减少噪音)并且如果您可以多次运行该关键部分(提高准确性),这将有所帮助。

于 2011-03-24T09:43:23.627 回答
1

在我看来,您所描述的方法以及许多评论似乎是理解性能影响的相对较弱的概率尝试。探查器对于 GUI 和其他空闲线程程序确实可以很好地工作,尽管阅读它们需要一些练习。不过,我认为您最好的选择就在那里——学习更好地使用分析器,这就是它的用途。

您描述的具体用途只是附加分析器但尚未记录。将 GUI 导航到有问题的点。点击探查器记录按钮,执行操作,然后停止记录。查看结果。使固定。再来一遍。

于 2011-03-24T13:29:44.390 回答
1

我假设应用程序执行中的某个阶段需要太长时间 - 即它让您等待。我假设您真正想要的是看看您可以更改哪些内容以使其更快。

一种有效的技术是随机暂停。您在调试器下运行应用程序,并在其执行部分让您等待、暂停并检查调用堆栈。这样做几次。

以下是您的程序可能会花费更多时间的一些方法。

  • 您不知道也不需要的 I/O。
  • 非常频繁地分配和释放对象。
  • 关于数据结构的失控通知。
  • 其他的不胜枚举……

不管它是什么,当它发生时,调用堆栈的检查就会显示出来。一旦你知道它是什么,你就可以找到更好的方法来做,或者根本不做。

如果程序在可能需要 1 秒的情况下需要 5 秒,那么您在每次暂停时看到问题的概率是 4/5。事实上,你在多个堆栈样本上看到的任何函数调用,如果你能避免这样做,都会给你带来显着的加速。而且,几乎所有可能的瓶颈都可以通过这种方式找到。

不要考虑函数计时或调用它们的次数。寻找那些经常出现在堆栈上的、你不需要的代码行。

添加的示例:如果您对堆栈进行 5 个样本,并且其中 2 个样本上出现了一行代码,那么它负责大约 2/5 = 40% 的时间,给或取。你不知道确切的百分比,你也不需要知道。(从技术上讲,平均为 (2+1)/(5+2) = 3/7 = 43%。还不错,而且您确切地知道它在哪里。)

于 2011-03-24T13:17:48.703 回答