首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java中的自动装箱与手动装箱

Java中的自动装箱与手动装箱
EN

Stack Overflow用户
提问于 2010-02-22 07:28:17
回答 3查看 12.8K关注 0票数 21

为什么第二段代码更快?

代码语言:javascript
复制
Map<Integer, Double> map = new HashMap<Integer, Double>();
for (int i = 0; i < 50000; i++) {
    for (double j = 0.0; j < 10000; j++) {
        map.put(i, j);
    }
}

Map<Integer, Double> map=new HashMap<Integer, Double>();
for (int i = 0; i < 50000; i++) {
    for (double j = 0.0; j < 10000; j++) {            
        map.put(new Integer(i), new Double(j));
    }
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-02-22 08:04:31

自动装箱使用Integer.valueOf,它在内部缓存Integer对象中的小整数(默认情况下为-128到127,但最大值可以通过"java.lang.Integer.IntegerCache.high“属性配置-参见Integer.valueOf的源代码),因此它不同于直接调用new Integer。因为Integer.valueOf在调用new Integer之前会快速检查整数值的大小,所以直接调用new Integer会更快一些(尽管如果有很多小整数,它会使用更多的内存)。Java中的分配非常快,并且进行GC的时间与活动的短期对象的数量成正比(即与垃圾的数量不成比例),因此GC也非常快。

但是,根据JVM的版本和启用的优化,存在标量替换优化,它在分配短期对象时会产生更大的性能差异(在您的示例中,无法进行优化,因为您将对象存储在映射中,但在许多其他情况下,它是有用的)。

在最近的JVM版本中有scalar replacement优化(除了在1.6.0_18中,它的逸出分析是temporarily disabled),这意味着可以优化短期对象的分配。当JVM中的标量替换是新的时候,有人制作了a benchmark,其中有类似于您的代码。结果是,使用原语的代码最快,使用显式new Integer()调用的代码几乎和使用原语的代码一样快,而使用自动装箱的代码要慢得多。这是因为自动装箱使用Integer.valueOf,至少在那时标量替换优化没有考虑到这种特殊情况。我不知道从那以后优化有没有改进。

票数 48
EN

Stack Overflow用户

发布于 2010-02-22 07:31:24

自动装箱将使用Integer.valueOfDouble.valueOf。调用这些方法会有一些开销(尽管它最终会被内联)。此外,Integer.valueOf还对低值进行了一些检查,以使用池化实例,这在代码中并不常见(尽管它可以稍微减少堆大小)。池化实例可能是一个胜利,因为它们减少了堆大小,GC时间,甚至可以提高相等测试性能。

但是,一般来说,这是一个微优化,一般情况下,您应该忽略它。

票数 14
EN

Stack Overflow用户

发布于 2010-02-22 07:30:27

因为微基准的结果是不可靠的?

此外,自动装箱是使用Integer.valueOf()和Double.valueOf()完成的,而不是使用构造函数。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2307904

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档