自动装箱的性能影响 [英] Performance impact of autoboxing

查看:109
本文介绍了自动装箱的性能影响的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Usually the compiler generates code to perform boxing and unboxing. But what does the compiler, if the boxed values are not needed? Is the (Oracle standard) compiler smart enough to optimize it away?

看看这个方法:

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

唯一相关的信息是 array.length ,所以例如,将数组的每个值都包装起来是没用的。喜欢这段代码:

The only relevant information is the array.length, so it would be useless to box each value of an array for example. Like in this code:

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

编译器是否会实际插入用于装箱数组中每个值的代码?

Will the compiler actually insert code for boxing each value of the array?

推荐答案

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

There is no autoboxing in your code. In fact, given:

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

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

虽然 int 可以自动装箱到整数 int [] NOT 自动装箱到 Java的整数[] 。您可以编写库函数来执行此操作,但该语言不会促进此转换。

While an int can be autoboxed to an Integer, an int[] does NOT get autoboxed to Integer[] by Java. You can write library functions to do this, but the language will not facilitate this conversion.

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

This is in fact the source of many confusion regarding e.g. Arrays.asList(anIntArray) being "broken", because instead of returning a List<Integer>, what is returned is in fact a one-element List<int[]>.

来自 Java语言指南/ Autoboxing


它不适合使用自动装箱和拆箱进行科学计算或其他对性能敏感的数字代码。 Integer 不能替代 int ; autoboxing和unboxing模糊了原始类型和引用类型之间的区别,但它们并没有消除它。

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.

简而言之,每当自动装箱发生时,性能肯定需要一点点。某些事情有助于缓解这种情况,例如:这些类型中内置的缓存机制。这就是为什么你得到以下内容:

In short, whenever autoboxing happens, performance definitely takes a little bit of a hit. Certain things help to alleviate this, e.g. the caching mechanism built into these types. This is why you get the following:

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

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

这里发生的是<$ c时$ c> 0 自动装箱,没有 整数实例实际创建:某些范围内的值缓存用于自动装箱,以帮助提高性能。大多数实现中的 10000 可能超出此范围,但是一些JVM实现允许您在必要时指定缓存范围。

What happened here is that when 0 is automatically boxed, no new Integer instance is actually created: values in certain range is cached for autoboxing purposes, to help performance. 10000 in most implementation probably falls out of this range, but some JVM implementations do allow you to specify the cache range if necessary.

有很多方法可以帮助您的 requireInRange 可以使用任何类型的数组。不幸的是,使用Java的原语数组通常意味着很多重复。这意味着为 int [] boolean [] byte [] 对象[] 等。另外。

There are many ways to facilitate your requireInRange to work with any type of arrays. Unfortunately working with Java's array of primitives often times mean lots of repetition. This mean providing overloads for int[], boolean[], byte[], Object[], etc separately.

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

A more concise option is to use reflection, but this has its pluses and minuses. Generally speaking, reflection should not be the preferred solution for most scenarios.

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

Having said that, java.lang.reflect.Array does have a int getLength(Object array) static method that can return the length of ANY array. It's not typesafe (like most reflection mechanism are); passing a non-array compiles, but throws IllegalArgumentException at run-time.

  • Managing highly repetitive code and documentation in Java - ("inspired" by java.util.Arrays)

这篇关于自动装箱的性能影响的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆