如果分析器不是答案,我们还有其他的选择吗?

在看了Joshua Bloch的“表现焦虑”的演讲之后,我阅读了他在“评估Java Pro fi lers准确性”的文章中提出的论文。 引用结论:

我们的结果是令人不安的,因为它们表明,在我们的七个基准中的大部分和两个生产JVM中,普遍存在的错误是普遍存在的,并且显着的是,所有四个最先进的专家都会产生错误的配置文件。 不正确的配置文件很容易导致性能分析人员花费时间优化对性能影响最小的冷​​方法。 我们证明,不使用屈服点进行抽样的概念证明不受上述问题的困扰

本文的结论是我们不能真正相信轮廓仪的结果。 但是,那么使用轮廓仪的选择是什么? 我们应该回去,只是用我们的感觉做优化?

更新 :在讨论中似乎被忽略的一点是观察者效应 。 我们可以建立一个真正的“ 观察者效应 ”分析器吗?

哦,男人,从哪里开始?

首先,我很惊讶这是新闻。 其次,问题不是轮廓不好,而是有些轮廓不好。 作者建立了一个他们认为是好的,只是避免了他们在评估中发现的一些错误。 由于关于性能分析的一些持续的神话,错误是常见的。

但是,让我们积极。 如果你想找到加速的机会,那真的很简单:

  • 抽样应该与节目的状态不相关
    这意味着在一个真正的随机时间发生,无论程序是否在I / O(用户输入除外),GC中,或在一个紧密的CPU循环,或其他。

  • 采样应该读取函数调用堆栈
    以确定样本中哪些语句是“活动的”。 原因是每个调用站点(调用函数的地方)的百分比成本等于它在堆栈上的时间比例。 (注:本文完全关注自我时间,忽略了大型软件中可避免的函数调用的巨大影响,实际上,原始gprof背后的原因是为了帮助找到这些调用)。

  • 报告应该按行显示(而不是按功能)。
    如果一个“热”功能被识别出来,还需要在里面寻找占用时间的“热门”代码行。 这些信息在样本中 ! 为什么要隐藏它?

一个几乎普遍的错误(即纸张份额)对测量的准确性要关心得太多,而且对位置的准确性不够。 例如,这里是一个性能调优的例子,其中一系列性能问题被识别和修复,导致43倍的复合加速。 在确定每个问题的大小之前,确定每个问题的大小并不是必须的,而是知道它的位置。 性能调整的一个现象就是解决一个问题,通过缩短时间,放大剩余问题的百分比,使其更容易找到。 只要发现问题并加以解决,就会发现并解决所有问题。 以减小尺寸顺序来修复它们并不是必须的,但是查明它们是非常重要的。

关于统计测量的准确性,如果一个呼叫点在堆栈上,F时间的百分比(如20%)和N个(如100个)随机时间采样被采样,那么显示呼叫的采样数量点是二项分布,平均值= NF = 20,标准偏差= sqrt(NF(1-F))= sqrt(16)= 4。因此,显示它的样本百分比将是20%+/- 4% 。 那准确的呢? 不是真的,但有问题被发现? 恰恰。

事实上,就百分比而言,问题越大,定位所需的样本就越少。 例如,如果采取3个样本,并且其中2个呼叫点出现,则很可能是非常昂贵的。 (具体来说,它是一个beta分布,如果你生成4个统一的0,1个随机数,并对它们进行排序,那么第3个分布就是这个分析点的成本分布,它的平均值是(2 + 1)/ 3 + 2)= 0.6,所以这是预期的节省,因为这些样本。)插入:你得到的加速因子由另一个分布BetaPrime控制平均值为4.所以,如果你拿3个样本,看到其中2个问题,并消除这个问题,平均来说,你会使程序快四倍。

现在是我们程序员在分析主题的时候把我们头脑中的蜘蛛网弄得一团糟的时候了。

免责声明 – 本文未能引用我的文章:Dunlavey,“使用调用堆栈抽样导出的指令级成本进行性能调优”,ACM SIGPLAN公告42,8(2007年8月),第4-8页。

如果我正确阅读, 本文只谈论基于样本的分析 。 许多配置文件也做基于工具的配置文件。 这个速度要慢得多,还有一些其他的问题,但是不应该受到这篇论文所说的偏见的影响。

本文的结论是我们不能真正相信轮廓仪的结果。 但是,那么使用轮廓仪的选择是什么?

不。本文的结论是目前的轮廓仪的测量方法有特定的缺陷。 他们提出一个解决方案 这篇文章是相当近的。 我希望分析器最终实现这个修复。 在此之前,即使是有缺陷的分析器仍然比“感觉”好得多。

除非您正在构建需要每个CPU周期的尖端应用程序,否则我发现分析器是查找代码中速度最慢的10%的好方法。 作为一名开发人员,我认为在几乎所有情况下都应该是你真正关心的。

我有与http://www.dynatrace.com/en/的经验,我可以告诉你,这是非常好找到低垂果实。;

Profiler与其他任何工具一样,他们有他们的怪癖,但我会信任他们在任何一天人类在您的应用程序中查找热点。

如果你不信任分析器,那么你可以通过使用面向方面的编程进入偏执狂模式,在你的应用程序的每个方法中包装,然后使用记录器记录每个方法的调用。

你的应用程序真的会慢下来,但至少你会精确计算每个方法被调用的次数。 如果你还想看看每个方法需要执行多长时间,请绕过每个方法perf4j 。

将所有这些统计数据转储到文本文件后,使用一些工具来提取所有必要的信息,然后将其可视化。 我想这会给你一个很好的概述你的应用程序在某些地方的速度有多慢。

事实上,你最好在数据库级别进行分析。 大多数企业数据库都能够在一段时间内显示最热门的查询。 开始研究这些查询,直到排名前300毫秒或更少,你将取得很大进展。 分析器对于显示堆的行为和识别被阻塞的线程很有用,但是我个人从来没有得到开发团队很多关于识别热方法或大对象的牵引力。