gpt4 book ai didi

java - 自动装箱的性能影响

转载 作者:搜寻专家 更新时间:2023-10-30 20:55:22 26 4
gpt4 key购买 nike

通常编译器生成代码来执行装箱和拆箱。但是,如果不需要装箱的值,编译器会怎么做? (Oracle 标准)编译器是否足够智能以优化它?

看看这个方法:

public static void requireInRange(int index, Object[] array) {
if(index < 0 || index >= array.length)
throw new IndexOutOfBoundsException();
}

唯一相关的信息是 array.length,因此将数组的每个值装箱是没有用的。就像在这段代码中:

int[] anArray = {3, 4, 2};
requireInRange(3, anArray);

编译器真的会插入代码来装箱数组的每个值吗?

最佳答案

您的代码中没有自动装箱。事实上,给定:

public static void requireInRange(int index, Object[] array) {
...
}

int[] anArray = {3, 4, 2};
requireInRange(3, anArray); // DOES NOT COMPILE!!!

虽然 int可以自动装箱到 Integer , 一个 int[] NOT 是否自动装箱为 Integer[]通过Java。您可以编写库函数来执行此操作,但该语言不会促进此转换。

这实际上是许多混淆的根源,例如Arrays.asList(anIntArray)被“破坏”,因为而不是返回 List<Integer> , 返回的实际上是一个单元素 List<int[]> .


但是性能呢???

引自 Java Language Guide/Autoboxing :

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.

简而言之,每当发生自动装箱时,性能肯定会受到一点影响。某些事情有助于缓解这种情况,例如这些类型中内置的缓存机制。这就是您获得以下内容的原因:

    System.out.println(
((Integer) 0) == ((Integer) 0)
);
// true

System.out.println(
((Integer) 10000) == ((Integer) 10000)
);
// false (implementation-specific)

这里发生的事情是当0 自动装箱,没有 Integer实际创建实例:特定范围内的值被缓存用于自动装箱目的,以帮助提高性能。 10000在大多数实现中可能不在这个范围内,但一些 JVM 实现确实允许您在必要时指定缓存范围。


但是我只想得到数组的长度!!!

有很多方法可以方便您requireInRange使用任何类型的数组。不幸的是,使用 Java 的基元数组通常意味着大量的重复。这意味着为 int[] 提供重载, boolean[] , byte[] , Object[] , 等等。

一个更简洁的选择是使用反射,但这有其优点和缺点。一般来说,反射不应该是大多数场景的首选方案。

话虽如此, java.lang.reflect.Array 确实有 int getLength(Object array) static可以返回 ANY 数组长度的方法。它不是类型安全的(就像大多数反射机制一样);传递一个非数组编译,但抛出 IllegalArgumentException在运行时。

相关问题

关于java - 自动装箱的性能影响,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3430671/

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