auto boxing带来的性能损耗

我们都知道int之类的基本类型是无法直接加入到collection中的,collection中只能放置对象的引用,所以在把基本类型添加到collection中时需要把基本数据类型包装为对应的包装类,如下:

1   List list = new ArrayList();
2   list.add(new Integer(10));

在JDK5种添加了一个新特性叫auto boxing(自动装箱),我们可以直接向collection中添加基本数据类型,看上去好像是collection支持添加基本数据类型了,但事实上是编译器自动帮你将基本数据类型转化为了对应的包装类,如下:

1   List<Integer> list = new ArrayList<Integer>();
2   list.add(10);

这样大大减少了我们要编写的代码,也让我们在大多数场景下不必关心基本数据类型与对应包装类型的互相转换的问题,可是在性能敏感的系统里面如果滥用甚至误用auto boxing是会带来很大的性能影响的。让我们看看如下代码:

 1 import java.util.*;
 2 
 3 public class OtherTest {
 4 
 5     private static Map<String, Double> map = new HashMap<String, Double>();
 6     static {
 7         for (int i = 0; i < 1000000; i++) {
 8             map.put("" + i, Double.valueOf(i + 0.1));
 9         }
10     }
11 
12     public static void main(String[] args) {
13         bad();
14 //        good();
15     }
16 
17     private static void bad() {
18         Double sum = 0d;
19         for (int i = 0; i < 1000000; i++) {
20             Double d = map.get("" + i);
21             sum += d;
22         }
23         System.out.println("result is: " + sum);
24     }
25 
26     private static void good() {
27         double sum = 0d;
28         for (int i = 0; i < 1000000; i++) {
29             Double d = map.get("" + i);
30             sum += d;
31         }
32         System.out.println("result is: " + sum);
33     }
34 }

在Profiler中我们可以看到bad()和good()两个方法执行情况的对比:

 

 

从上图可以看到,bad()方法会生成更多的Double对象,这导致GC执行得更频繁、时间更长。那我们该什么时候使用auto boxing呢?官方给出的解释是:

So when should you use autoboxing and unboxing? Use them only when there is an “impedance mismatch” between reference types and primitives, for example, when you have to put numerical values into a collection. It is not appropriate to use autoboxing and unboxing for scientific computing, or other performance-sensitive numerical code. An Integer is not a substitute for an int; autoboxing and unboxing blur the distinction between primitive types and reference types, but they do not eliminate it.

当你需要将数值放到一个collection中或类似必须进行基本类型与对象的转换时才使用auto boxing,而在科学计算或其他性能敏感的系统里一定要谨慎使用。

posted @ 2013-10-24 10:24  寂灵天  阅读(396)  评论(0)    收藏  举报