Question

Does the javac or JIT optimize unnecessary autoboxing? Let's say we have a this fragment of code.

for(int i=0; i<100000; i++) {
    f(i);
}

void f(Integer i) {
    System.out.println(i);
}

How this fragment of code gets optimized? I guess f will be inlined, but what about unnecessary boxing of int (it's not being modified and never is null). Let's assume the method is not called from any other fragment of code. Will there be any difference if the method signature was
void f(final Integer i)?

No correct solution

OTHER TIPS

The OpenJDK and HotSpot JVM 5 - 8 don't optimise them away, unless they are not used (and even then not always)

However, it is important to have a sense of perspective when you ask these problem or answer them. Autoboixing is trivial compared to the code of converting a number into a String (the way the JVM does it anyway) and this is trivial by comparison to writing to the console. If you take out the System.out.println() this will save 99.99%+ of the time so worrying about autoboxing here is worrying about the wrong things.

In your specifc case, it cannot optimise way the autoboxing because PrintStream.println(Object) is called. The JVM generally doesn't understand what libraries do and it can't make the assumption that calling PrintStream.println(int) would do the same thing.

The JVM is free to do whatever optimisation it likes, so it is possible that some JVMs would optimise this.

It's bad practice to assume it will though and for every JVM that does there may well be several that don't.

Just change the method to accept the type in the same level of boxing as it uses inside it..

When you take a look at this:

public class a
{
    public static void main(String[] args)
    {
        for (int i = 0; i < 100000; i++)
            f(i);
    }

    public static void f(Integer i)
    {
        System.out.println(i);
    }
}

and see what it looks like after calling javac a.java && javap -c a, you'll get

Compiled from "a.java"
public class a {
  public a();
    Code:
       0: aload_0       
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return        

  public static void main(java.lang.String[]);
    Code:
       0: iconst_0      
       1: istore_1      
       2: iload_1       
       3: ldc           #2                  // int 100000
       5: if_icmpge     21
       8: iload_1       
       9: invokestatic  #3                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
      12: invokestatic  #4                  // Method f:(Ljava/lang/Integer;)V
      15: iinc          1, 1
      18: goto          2
      21: return        

  public static void f(java.lang.Integer);
    Code:
       0: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;
       3: aload_0       
       4: invokevirtual #6                  // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
       7: return        
}

This bytecode shows us that Integer.valueOf() is being called (main 9:), therefore no optimization takes place in this case at the compilation level. However, as @Tim B has pointed out, what happens inside JVM is another matter which can't be predicted. It is best to assume the worst-case scenario - JVM won't optimize it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top