编译时Java常量表达式相关代码的优化
下面是一个关于Java编译优化的简单问题 是 等于编译时Java常量表达式相关代码的优化,java,Java,下面是一个关于Java编译优化的简单问题 是 等于 final int CONSTANT_NUMBER=7; 编译代码还是性能方面?从编译来看,第二个肯定会快一点,因为它首先有一个方法调用。然而,如今的机器速度太快了,这一点已经不明显或不重要了 为了提高性能,现代编译器应该聪明地看到“foobar”是一个常量,应该将表达式替换为length。但是,如果您将该行更改为变量,那么您可能会欺骗编译器每次调用该方法,如果在大循环中运行,则使1st稍微快一点 我通过让它们在一个大循环中运行来测试这一点,
final int CONSTANT_NUMBER=7;
编译代码还是性能方面?从编译来看,第二个肯定会快一点,因为它首先有一个方法调用。然而,如今的机器速度太快了,这一点已经不明显或不重要了 为了提高性能,现代编译器应该聪明地看到“foobar”是一个常量,应该将表达式替换为length。但是,如果您将该行更改为变量,那么您可能会欺骗编译器每次调用该方法,如果在大循环中运行,则使1st稍微快一点 我通过让它们在一个大循环中运行来测试这一点,第二种方法的性能稍好一些。我猜我的编译器不够聪明,不能用常量替换方法调用
因此,在我的机器上,简短的回答、性能方面的直接int比方法调用要好,但在不同的编译器上可能会有所不同。否java编译器在编译时不会计算
“Foo Bar”.length()
以这些类为例
public class ConstantCheck {
final int CONSTANT_NUMBER = "Foo Bar".length();
}
及
在编译的.class
文件上使用javap-v
,可以看到.length()
调用被保留:
前者导致
...
final int CONSTANT_NUMBER;
descriptor: I
flags: ACC_FINAL
public text.ConstantCheck();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: ldc #2 // String Foo Bar
7: invokevirtual #3 // Method java/lang/String.length:()I
10: putfield #4 // Field CONSTANT_NUMBER:I
13: return
...
在第二种情况下,它只是一个写入字段的常量
5: bipush 7
7: putfield #2 // Field CONSTANT_NUMBER:I
编译代码和性能是不相等的。是的,当然,但是其中一个会强烈影响另一个。非常感谢!这正是我想要的!:黛雅:看到这一点很不幸。我认为编译器能够检测到这样的代码。
...
final int CONSTANT_NUMBER;
descriptor: I
flags: ACC_FINAL
public text.ConstantCheck();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: ldc #2 // String Foo Bar
7: invokevirtual #3 // Method java/lang/String.length:()I
10: putfield #4 // Field CONSTANT_NUMBER:I
13: return
...
...
final int CONSTANT_NUMBER;
descriptor: I
flags: ACC_FINAL
ConstantValue: int 7
public text.ConstantCheck();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=2, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: bipush 7
7: putfield #2 // Field CONSTANT_NUMBER:I
10: return
....
7: invokevirtual #3 // Method java/lang/String.length:()I
5: bipush 7
7: putfield #2 // Field CONSTANT_NUMBER:I