Java 为什么在这个循环中使用缓存整数(-128到127)的操作比使用非缓存整数的操作慢?

Java 为什么在这个循环中使用缓存整数(-128到127)的操作比使用非缓存整数的操作慢?,java,performance,Java,Performance,我有一个简单的程序: 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++) {

我有一个简单的程序:

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);
    }
}
  • 对象创建不是一个缓慢的操作。在Java的早期,它的速度很慢,如果将大型复杂对象的初始化时间包括在内,它可能仍然很慢。但是创建一个小的单场对象是一个非常快速的操作
  • 尽管如此,不创建大量对象的建议仍然是相关的,因为它们会浪费内存。内存不足时,垃圾回收器将运行并降低程序速度
  • 当一个整数被装箱时,它运行
    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);
    }
    

    结论:如果您分配了许多对象,当您有大量内存时,它可能会稍微快一点,但当您只有很少的内存并且需要垃圾收集时,它会明显慢一点。

    可能是因为JVM不必查找已兑现的版本。此外,GC可能与escape分析无关。JIT优化了常见用例,当您提出一个虚构的示例时(实际上没有人会这么做),它可能会给出奇怪的结果。JVM需要一些时间来检查缓存中的值。它发生在-127-+127。对于大的数字,它不会这样做,因此速度更快。你可能会发现这与此相关。
    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
    
    $ 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