我有一个简单的程序:
public class Main {
public static void main(String[] args) {
long sum = 0L;
long start = System.currentTimeMillis();
for (int i = 0; i < 10000000; i++) {
for (Integer j = 0; j < 100; j++) {
sum++;
}
}
System.out.println(System.currentTimeMillis() - start);
System.out.println(sum);
}
}
在我的机器上,这将在大约3300毫秒内执行。
当我将内循环中j
变量的范围更改为:
for (Integer j = 1000; j < 1100; j++)
它在大约2500毫秒内执行。
我希望第二个版本的执行速度要慢得多,因为每次迭代都应该创建一个新的Integer
。但它实际上更快。为什么呢?
Java版:
java version "1.8.0_65"
Java(TM) SE Runtime Environment (build 1.8.0_65-b17)
Java HotSpot(TM) 64-Bit Server VM (build 25.65-b01, mixed mode)
答案 0 :(得分:3)
当整数被装箱时,它会运行Integer.valueOf(int)
。该方法的来源是:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
这意味着对于小数字,有:
对于大数字,有:
根据您的设置,对象分配可能会更快。在我的Mac上,这两个版本之间差别不大。在我的Linux上,我看到了与你描述的相同的结果。
了解内存受到压力时的行为有多么不同。
-Djava.lang.Integer.IntegerCache.high=1500
添加到java命令行,使缓存中包含范围1000-1100。-Xmx5M
我的Linux机器上的典型结果(Oracle Java 1.8):
$ java Main 2575 1000000000 $ java -Djava.lang.Integer.IntegerCache.high=1500 Main 3078 1000000000 $ java -Xmx5M Main 5812 1000000000 $ java -Xmx5M -Djava.lang.Integer.IntegerCache.high=1500 Main 3102 1000000000
结论:如果你分配了很多对象,当你拥有大量内存时,它可能会稍快一点,但是当你需要很少的内存并且需要垃圾收集时,它会明显变慢。