java - 为什么这种方法成为热点?

标签 java performance optimization visualvm

我正在编写一个(简单!)线性代数库。在执行matrix multiplication , 一个 VisualVM性能示例告诉我,在乘以大型矩阵 (5k x 120k) 时,该算法在以下方法中花费了 85% 的时间(特别是“ self 时间”):

public double next() {
    double result;

    if(hasNext())
        result = vis[i++].next();
    else
        throw new IllegalStateException("No next value");

    return result;
}

无需赘述(抱歉,我无法分享更多代码),此方法是矩阵“迭代器”的 next() 方法。 (您可以将此方法所在的类想象成一个由单独的列迭代器组成的行迭代器,这些迭代器存储在 vis 中。)我对此方法被频繁调用并不感到惊讶,因为它是一个迭代器,但令我惊讶的是该程序在该方法中花费了大量时间。这个方法做的不多,为什么要花时间在这里呢?

以下是我要问的具体问题:

  1. 我遇到了 VisualVM 的一些“陷阱”吗?例如,JIT 是否会以某种方式混淆 VisualVM,导致 VisualVM 将时间归因于错误的方法?
  2. 为什么程序要花时间在这里?该方法只是没有做太多。特别是,我不认为缓存效应可以解释这个问题,因为 vis 数组比要相乘的矩阵数据小得多。

如果它有用,这里有一个 jad反汇编我上面粘贴的方法:

public double next()
{
    double result;
    if(hasNext())
//*   0    0:aload_0         
//*   1    1:invokevirtual   #88  <Method boolean hasNext()>
//*   2    4:ifeq            32
        result = vis[i++].next();
//    3    7:aload_0         
//    4    8:getfield        #42  <Field VectorIterator[] vis>
//    5   11:aload_0         
//    6   12:dup             
//    7   13:getfield        #28  <Field int i>
//    8   16:dup_x1          
//    9   17:iconst_1        
//   10   18:iadd            
//   11   19:putfield        #28  <Field int i>
//   12   22:aaload          
//   13   23:invokeinterface #72  <Method double VectorIterator.next()>
//   14   28:dstore_1        
    else
//*  15   29:goto            42
        throw new IllegalStateException("No next value");
//   16   32:new             #89  <Class IllegalStateException>
//   17   35:dup             
//   18   36:ldc1            #91  <String "No next value">
//   19   38:invokespecial   #93  <Method void IllegalStateException(String)>
//   20   41:athrow          
    return result;
//   21   42:dload_1         
//   22   43:dreturn         
}

在此先感谢您的帮助!

最佳答案

我发现这个方法看起来像一个热点,因为 VisualVM 被指示在其分析中忽略来自 JRE 的方法。花在那些“被忽略”方法上的时间(表面上)被卷入调用堆栈最顶层未被忽略的条目的自身时间。

下面是 VisualVM 中的设置屏幕,包括导致数据错误的“不分析包”设置。要调整“忽略类别”设置,您必须 (1) 单击以红色突出显示的“设置”复选框,然后 (2) 调整以蓝色突出显示的类别设置。

VisualVM Settings Screen

根据您的操作,至少不要忽略 java.*javax.* 包可能是有意义的。

关于java - 为什么这种方法成为热点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16065668/

相关文章:

performance - 为什么 Cases[] 在这里这么慢?有什么技巧可以加快速度吗?

java - 如何确保文件仅由 Java 中的多线程从磁盘加载一次

python - 优化忽略某些标签值的损失函数

java - 在 Gradle 中使用 DBDeploy 并使用 hibernate 作为 ORM

java - 如何将 View 移动到屏幕最近的边缘?

c++ - C++ 中 "if error then fail fast"的性能损失?

java - 为什么JVM仍然不支持尾调用优化?

python - Python 中的字符串覆盖优化

java - 某个值在哈希表中出现的次数

java - 使用 Bloomberg 获取 Java 特定时间的最后一笔交易