Java中的.getClass()有多贵?

mim*_*pus 10 java

我正在将某个数据处理算法从Java移植到C++.重写代码的原因是可移植性,它需要在Java不可用的环境中运行.然而,作为附带的好处,预计会有一些性能提升.

基本上,该算法从由具有彼此指针的对象组成的图中读取数据,然后计算结果.在计算过程中会进行大量的对象分配,因此这可能是造成减速的原因.问题是,C++代码目前运行速度比旧Java代码快10倍.这真是出乎意料.我只觉得我会看到改善50-60%.

不幸的是,我不能自由地在这里发布代码进行分析.这是几千行,所以我不确定无论如何都会有多方便.

问题是,算法几乎完全相同.我能想到的唯一主要区别是在Java中有一个超级类的子类很多,if(object.getClass()== daughterx.class)在计算过程中被多次调用而在C++代码中只有一个通用使用class(因为子类之间的代码差异很少)并且使用简单的整数比较,例如.if(object-> type == 15)

Java中的Object.getClass()方法有多贵?调用此方法时,在低级别发生了什么?

Ste*_*n C 13

Java中的Object.getClass()方法有多贵?

基于我对如何在非主流JVM中实现它的知识,它很便宜

调用此方法时,在低级别发生了什么?

通常......

  1. 从对象的标题中提取类索引(2或3条指令)
  2. 从类索引中查找类描述符(2或3条指令)
  3. Class从类描述符中获取并返回对象引用(2或3条指令)

问题是,C++代码目前运行速度比旧Java代码快10倍.

我希望性能瓶颈在其他地方.您应该尝试分析Java代码,然后才能得出任何结论,以了解它为何变慢.

  • +1虽然查找本身很便宜,但如果你有`if(getClass()== SomeClass.class)的序列,它意味着一个重要的设计和性能问题.它表明你需要更多的OO设计或者OP需要,结合这些类因此可以使用开关等来实现功能. (6认同)

Pet*_*rey 8

10倍差异的最可能的情况是JVM没有完全预热.如果不这样做,即使在Java中也可以看到超过10倍的性能差异.我会尝试分批运行10,000次并忽略前几次运行.

public static void main(String... args) throws IOException {
    timeObjectGraph("First run", 1);
    timeObjectGraph("Second run", 2);
    timeObjectGraph("Next thousand", 1000);
    for (int i = 0; i < 5; i++)
        timeObjectGraph("Next ten thousand", 10000);
}

static int dontOptimiseAway = 0;

public static void timeObjectGraph(String desc, int runs) throws IOException {
    long start = System.nanoTime();
    for (int i = 0; i < runs; i++) {
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(out);
        oos.writeObject(Calendar.getInstance());
        oos.close();
        dontOptimiseAway = out.toByteArray().length;
    }
    long time = System.nanoTime() - start;
    System.out.printf("%s took an avg time of %,d ns%n", desc, time / runs);
}
Run Code Online (Sandbox Code Playgroud)

版画

First run took an avg time of 37,509,488 ns
Second run took an avg time of 439,054 ns
Next thousand took an avg time of 185,242 ns
Next ten thousand took an avg time of 41,698 ns
Next ten thousand took an avg time of 19,981 ns
Next ten thousand took an avg time of 11,541 ns
Next ten thousand took an avg time of 13,451 ns
Next ten thousand took an avg time of 11,289 ns
Run Code Online (Sandbox Code Playgroud)

从第一次到最后一次运行,性能提高了3000倍

  • @Cherry我使用了Calendar和ObjectOutputStream,因为这些代码对于一小段代码来说都很昂贵,这给出了一个真实的例子,说明了热量可以为大量代码带来多大的差异. (2认同)

Ste*_*ker 5

它不可能是性能差异的唯一因素.不幸的是,如果没有更完整的代码实际上正在做什么,那么很难告诉你发生了什么.

根据我的经验,Java应该比C++慢10倍.我可能会从一个分析器开始,看看它指向何处理解问题,而不是猜测.