Dra*_*vic 6 java bytecode javac compiler-optimization
我有一个简单的类用于说明目的:
public class Test {
public int test1() {
int result = 100;
result = 200;
return result;
}
public int test2() {
return 200;
}
}
Run Code Online (Sandbox Code Playgroud)
编译器生成的字节码(检查者javap -c Test.class
)如下:
public int test1();
Code:
0: bipush 100
2: istore_1
3: sipush 200
6: istore_1
7: iload_1
8: ireturn
public int test2();
Code:
0: sipush 200
3: ireturn
Run Code Online (Sandbox Code Playgroud)
为什么编译器没有将test1
方法优化为为该方法生成的相同字节码test2
?我希望它至少可以避免result
变量的冗余初始化,因为很容易得出结论100
根本没有使用该值.
我用Eclipse编译器和javac
.
javac
version 1.8.0_72
:,与Java一起作为JDK的一部分安装:
Java(TM) SE Runtime Environment (build 1.8.0_72-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.72-b15, mixed mode)
Run Code Online (Sandbox Code Playgroud)
JVM优化字节码,创建了一个称为代码缓存的东西。与C ++不同,JVM可以收集有关程序的大量数据,例如,for循环有多热?,那个代码块甚至值得优化吗?等等。因此,此处的优化非常有用,通常可以产生更好的结果。
如果在从java转换为字节码时(即,当您调用javac时)进行了优化,则您的代码可能最适合您的计算机,但不适用于某些其他平台。因此,在此处进行优化没有任何意义。
例如,假设您的程序使用AES加密。现代CPU具有专用于AES的指令集,并带有专用硬件,以使加密速度大大提高。
如果javac尝试在编译时进行优化,则它将
如果相反,javac将它们保留在byptcode中,则在较新的CPU上运行的JVM可以将它们识别为AES并利用此CPU功能,而在较旧的CPU上运行的JVM可以在运行时在软件级别对其进行优化(代码缓存),从而你们既最优又兼容性。
典型的 Java 虚拟机在运行时优化程序,而不是在编译期间。在运行时,JVM 了解更多有关您的应用程序的信息,包括程序的实际行为以及执行程序的实际硬件。
字节码只是对程序应该如何运行的描述。运行时可以自由地对您的字节代码应用任何优化。
当然,有人可能会说,即使在编译期间也可以应用这种微不足道的优化,但一般来说,不将优化分布在多个步骤中是有意义的。任何优化都会有效地导致原始程序的信息丢失,这可能使其他优化变得不可能。也就是说,并非所有“最佳优化”总是显而易见的。一个简单的方法是在编译期间简单地删除(几乎)所有优化并在运行时应用它们。
归档时间: |
|
查看次数: |
423 次 |
最近记录: |