Java在创建对象时的表现

时间:2015-05-07 08:56:47

标签: java performance final

我试图提高我在Java性能优化方面的知识,并尝试了多种方法来创建对象 我遇到过这种行为,我对类中最终成员的使用并不熟悉:如果成员不是最终成员,则创建对象的成本要低得多(就时间而言)。它是正确的还是我的代码中有一些错误?

没有最终成员的对象:

public class ComplexNumber {
    private double re, im;

    public ComplexNumber(double _re, double _im) {
        re = _re;
        im = _im;
    }

    public void setRe (double _re) {
        re = _re;
    }

    public void setIm (double _im) {
        im = _im;
    }

    @Override
    public String toString() {
        return re + " + i" + im;
    }

    @Override
    public int hashCode() {
        return 47 + 31*(int)re + 31*(int)im;
    }
}  

具有最终成员的对象:

public class FinalComplexNumber {
    private final double re, im;

    public FinalComplexNumber(double _re, double _im) {
        re = _re;
        im = _im;
    }

    @Override
    public String toString() {
        return re + " + i" + im;
    }

    @Override
    public int hashCode() {
        return 47 + 31*(int)re + 31*(int)im;
    }
}  

主要课程

public class PerformanceTest {

    private static final long ITERATIONS = 100000000l;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {


        ComplexNumber nr = new ComplexNumber(0, 0);
        System.out.println(nr);

        long time = System.currentTimeMillis();
        for (int i = 0; i < ITERATIONS; i++) {
            ComplexNumber num = new ComplexNumber(i, i);
        }
        System.out.println(System.currentTimeMillis() - time);

        time = System.currentTimeMillis();
        for (int i = 0; i < ITERATIONS; i++) {
            nr.setIm(i);
            nr.setRe(i);
        }
        System.out.println(System.currentTimeMillis() - time);

        time = System.currentTimeMillis();
        for (int i = 0; i < ITERATIONS; i++) {
            FinalComplexNumber num = new FinalComplexNumber(i, i);
        }
        System.out.println(System.currentTimeMillis() - time);
    }
}  

结果:

run:
0.0 + i0.0
953
219
7875
BUILD SUCCESSFUL (total time: 9 seconds)

2 个答案:

答案 0 :(得分:9)

  

如果成员不是最终成员,那么创建对象的成本要低得多(就时间而言)。

不,绝对不是这样。基本上,您的基准测试方法已被打破:

  • 您正在使用NSPersistentStoreDidImportUbiquitousContentChangesNotification ,这通常是基准测试的一个坏主意; System.currentTimeMillis()首选用于衡量已用时间
  • 您没有提供任何JIT热身
  • 您不是使用您创建的对象,这可能允许在更正常的代码中无效的JIT优化
  • 你甚至没有尝试以内存垃圾的方式开始一个关卡游戏领域,所以你可能会发现你的第一个循环不需要执行任何垃圾收集,但你的最后一个循环呢。

您可能希望查看旨在避免此类问题的微基准测试框架,例如CaliperJMH

答案 1 :(得分:3)

以下是您如何研究增加决赛对绩效的影响:http://shipilev.net/blog/2014/all-fields-are-final/