【问题标题】:Best method to count byte codes executed for a Java code计算为 Java 代码执行的字节码的最佳方法
【发布时间】:2014-09-26 15:58:59
【问题描述】:

我试图获取各种 Java 程序的计时数据。然后我不得不根据这个时序数据进行一些回归分析。以下是我用来获取时序数据的两种方法:

  • System.currentTimeMillis():我最初使用这个,但我希望在同一程序多次运行时计时数据保持不变 次。在这种情况下,变化很大。当两个实例 相同的代码并行执行,变化更大。所以 我放弃了这个并开始寻找一些分析器。
  • Hotspot JVM 中的-XX countBytecodes Flag:由于时序数据的变化很大,所以我想测量执行此代码时执行的字节码的数量。当同一个程序被多次执行时,这应该给出更静态的计数。但这也有变化。当程序按顺序执行时,变化很小,但在相同代码的并行运行期间,变化很大。我也尝试使用-Xint进行编译,但结果相似。

所以我正在寻找一些分析器,它可以给我在执行代码时执行的字节码计数。在同一程序的运行中,计数应保持不变(或相关性接近 1)。或者,如果有其他一些指标,我可以根据这些指标获取计时数据,这些数据在多次运行中应该几乎保持不变。

【问题讨论】:

  • 我不知道。你为什么要这样做? VisualVM 是一个不错的分析器。但是在 JIT 优化了您的方法之后,您尝试收集的数据毫无意义,所以我不知道您如何收集数据。
  • @ElliottFrisch 我想根据执行时间性能对代码进行评分,并相互比较程序,根据性能相似的程序对数据进行聚类等。
  • 我认为这行不通。
  • 您为什么要排除特定时间与您的测量值不同的事实?这不会破坏他们的目的吗?
  • @ElliottFrisch 我正在使用-Xint 标志,它强制JVM 以解释模式执行所有字节码。所以那些优化位不应该出现。因此,这应该可以正常工作吗?

标签: java performance jvm profiler jprofiler


【解决方案1】:

我希望同一程序多次运行时计时数据保持不变

这在真实机器上是不可能的,除非它是为硬实时系统设计的,而你的机器几乎肯定不会。

我正在寻找一些分析器,它可以为我提供在执行代码时执行的字节码计数。

假设你能做到这一点,它不会证明任何事情。例如,您将无法看到 ++% 便宜 90 倍,具体取决于您运行它的硬件。您将无法看到 if 的分支未命中比投机分支的成本高出 100 倍。您不会看到对触发 TLB 未命中的内存区域的内存访问可能比复制 4 KB 数据更昂贵。

如果有其他指标可以让我获得计时数据,那么在多次运行中它应该几乎保持不变。

您可以多次运行它并取平均值。这将隐藏任何高结果/异常值,并为您提供良好的吞吐量概念。如果运行时间足够长,它可以是给定机器的可重现数字。

【讨论】:

  • 我知道情况并非如此,而且正如我所说的那样,变化很大。所以我将度量标准从执行时间更改为执行的字节码数。它们应该与计时数据有直接关系,并且在同一个程序多次运行时应该几乎保持不变。
  • @aichemzee 担心的是,即使您获得可重现的字节码字节数,它也不会告诉您有关应用程序的性能或时序的任何信息,例如Thread.sleep(100000);System.gc(); 中有多少字节
  • 是的,它不会。但是我根据输入大小变化时的缩放方式对代码进行评级。所以这样的陈述要么会影响常数项,要么会改变计时函数的系数,而不是改变计时函数本身。 (例如t(N)=C_1*N+C_2的时序函数,所以C_1和C_2都会受到影响,预测的时序函数仍然会呈现线性缩放)
  • @aichemzee 所以你想凭经验测量程序的时间复杂度?我可以编写一个对于任何实际输入总是 O(1) 的程序,但总是需要很长时间。 ;) 根据大量样本来衡量它运行了多长时间会不会更简单。这就是 JMH 等大多数基准测试工具的工作方式。
  • 你可以编写一个总是显示 O(1) 的程序。但是我拥有的示例认为基准测试将手动完成,因此代码很干净。 :D 我将在多次运行中进行平均分析,并查看结果。顺便谢谢。但是是的,多次运行会减慢速度,这很糟糕。
猜你喜欢
  • 2017-07-02
  • 1970-01-01
  • 1970-01-01
  • 2022-01-03
  • 1970-01-01
  • 1970-01-01
  • 2015-04-24
  • 2011-08-28
  • 1970-01-01
相关资源
最近更新 更多