gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-29 04:50:30 25 4
gpt4 key购买 nike

我有一个简单的程序:

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)

最佳答案

  • 对象创建不是一个缓慢的操作。在 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);
    }

    这意味着对于小数,有:

    • 对象字段的两次比较
    • 否定
    • 补充
    • 对象内的数组查找。

    对于大数,有:

    • 对象字段的两次比较
    • 小对象分配
    • 初始化为零
    • 赋值。

    根据您的设置,对象分配可能会更快。在我的 Mac 上,两个版本之间几乎没有区别。在我的 Linux 上,我看到了与您描述的相同的结果。

  • 了解当内存受到压力时它的行为有何不同是有教育意义的。

    • 在 1000 到 1100 值之间使用您的版本。
    • 您可以对缓存和非缓存测试使用相同的程序:将 -Djava.lang.Integer.IntegerCache.high=1500 添加到 java 命令行,使范围 1000-1100 包含在缓存。
    • 要在有和没有内存压力的情况下对其进行测试,请添加 -Xmx5M

我的 Linux 机器 (Oracle Java 1.8) 上的典型结果:

$ java Main25751000000000$ java -Djava.lang.Integer.IntegerCache.high=1500 Main30781000000000$ java -Xmx5M Main58121000000000$ java -Xmx5M -Djava.lang.Integer.IntegerCache.high=1500 Main31021000000000

结论:如果你分配很多对象,当你有很多内存时它可能会稍微快一些,但是当你有很少并且需要垃圾收集时它会明显变慢。

关于java - 为什么在此循环中使用缓存整数(-128 到 127)的操作比使用非缓存整数的操作慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35585636/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com