Java自动装箱性能比较

Java自动装箱性能比较,java,performance,autoboxing,Java,Performance,Autoboxing,大家好,我正在阅读有效的Java,在第6项:避免创建不必要的对象中,有一个示例建议对装箱的原语使用原语来避免不必要的对象创建 作者说,在我的机器上,将sum的声明从Long改为Long将运行时间从43秒减少到6.8秒。接下来,教训是明确的:与装箱的原语相比,更喜欢原语,并且要注意无意的自动装箱 但是当我在我的机器上运行它时,原始版本比盒装版本慢 上述程序的输出: 长和耗时:5905毫秒 长和耗时:7013毫秒 结果并不像作者所说的那样,变量sum被声明为Long而不是Long,这意味着程序构造了

大家好,我正在阅读有效的Java,在第6项:避免创建不必要的对象中,有一个示例建议对装箱的原语使用原语来避免不必要的对象创建

作者说,在我的机器上,将sum的声明从Long改为Long将运行时间从43秒减少到6.8秒。接下来,教训是明确的:与装箱的原语相比,更喜欢原语,并且要注意无意的自动装箱

但是当我在我的机器上运行它时,原始版本比盒装版本慢

上述程序的输出:

长和耗时:5905毫秒

长和耗时:7013毫秒

结果并不像作者所说的那样,变量sum被声明为Long而不是Long,这意味着程序构造了大约2^31个不必要的Long实例,每次Long i被添加到Long sum中,大约一个实例


为什么使用原语比使用对象慢?

您没有重置第二次测量的起点。基本性能实际上是两个值的时间差,这明显优于包装器。试试这个:

    // Hideously slow program! Can you spot the object creation?
    Long sum = 0L;
    for (long i = 0; i < Integer.MAX_VALUE; i++) {
        sum += i;
    }
    end = System.currentTimeMillis();
    System.out.println("Long sum took: " + (end - start) + " milliseconds");
    
    long sum2 = 0L;
    for (long i = 0; i < Integer.MAX_VALUE; i++) {
        sum2 += i;
    }
    end = System.currentTimeMillis();
    System.out.println("long sum took: " + (end - start) + " milliseconds");

它不能再慢了——你可能没有测量你认为你在测量的东西。有用阅读:上面的代码缺少一些声明。是否可能只在第一个循环之前分配start?在您的代码中,您只有1个starttime,例如,如果您从0长和开始,则需要检查并花费5905毫秒,并且您没有设置starttime,那么长sum2的时间将是长和+长sum2,以便获得长sum2的时间结束-开始-长sumtime。所以sum2很可能是1108@Keppil哎哟你是对的。愚蠢的错误。对我来说,作者是正确的,sum+=i,其中sum是长的,需要自动装箱并将其转换回原语。。来回地我希望这比只使用基元类型要慢。
// Hideously slow program! Can you spot the object creation?
Long sum = 0L;
start = System.currentTimeMillis();
for (long i = 0; i < Integer.MAX_VALUE; i++) {
    sum += i;
}
end = System.currentTimeMillis();
System.out.println("Long sum took: " + (end - start) + " milliseconds");

long sum2 = 0L;

// reset start!!
start = System.currentTimeMillis();

for (long i = 0; i < Integer.MAX_VALUE; i++) {
    sum2 += i;
}
end = System.currentTimeMillis();
System.out.println("long sum took: " + (end - start) + " milliseconds");