繁体   English   中英

JVM是否优化了不必要的自动装箱?

[英]Does the JVM optimize unnecessary autoboxing?

javac或JIT是否优化了不必要的自动装箱? 假设我们有一段代码片段。

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

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

这段代码如何得到优化? 我想f会被内联,但是不必要的int装箱(它没有被修改,永远不会是null )。 我们假设该方法不是从任何其他代码片段调用的。 如果方法签名是,那么会有什么不同吗?
void f(final Integer i)

OpenJDK和HotSpot JVM 5 - 8不会对它们进行优化,除非它们没有被使用(即使不是这样)

但是,当您提出这些问题或回答问题时,重要的是要有一种透视感。 与将数字转换为String(无论如何JVM的方式)相比,Autoboixing是微不足道的,与写入控制台相比,这是微不足道的。 如果您取出System.out.println(),这将节省99.99%以上的时间,所以担心自动装箱在这里担心错误的事情。

在您的特定情况下,它无法优化自动装箱的方式,因为调用了PrintStream.println(Object)。 JVM通常不了解库的作用,也不能假设调用PrintStream.println(int)会做同样的事情。

JVM可以自由地进行任何优化,因此有些JVM可能会对此进行优化。

假设它会是不好的做法,并且对于那些可能有几个不可能的JVM。

只需更改方法以接受与其内部使用相同级别的拳击类型。

当你看一下这个:

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);
    }
}

并且在调用javac a.java && javap -ca之后看看它是什么样的,你会得到的

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        
}

这个字节码向我们显示正在调用Integer.valueOf()main 9: Integer.valueOf() ,因此在这种情况下在编译级别不会进行优化。 但是,正如@Tim B指出的那样, JVM内部发生的事情是另一个无法预测的问题。 最好假设最坏的情况--JVM不会优化它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM