[英]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.