[英]why doesn't the java compiler rewrite this code?
我正在测试这段代码:
public class TestNull {
public void leftComparison(String s) {
if (s == null);
}
public void rightComparison(String s) {
if (null == s);
}
}
我用javac 1.8.0_05编译它,然后检查字节码:
public class TestNull {
....
public void leftComparison(java.lang.String);
Code:
0: aload_1
1: ifnonnull 4
4: return
public void rightComparison(java.lang.String);
Code:
0: aconst_null
1: aload_1
2: if_acmpne 5
5: return
}
显然, leftComparison
被编译为在堆栈上推送和弹出1个变量,而rightComparison
推送和弹出2.我推测leftComparison
因此比rightComparison
稍微有效?
我想知道为什么编译器不会重写rightComparison
的代码? 在我看来,这两个比较应该在语义上是等价的,对吧?
Java字节码编译器在优化方面做得很少。 严重的优化工作几乎全部由JIT编译器完成。
我想知道为什么编译器不会重写rightComparison的代码?
因为重写它没有意义。 JIT编译器应该能够处理它们,并且很可能为这两个版本生成最佳(本机)代码。 (如果您感兴趣,可以检查一下。有很多方法可以查看JIT编译器生成的本机代码。)
(另请参阅@ codenheim的答案以获得更多技术解释。)
在我看来,这两个比较应该在语义上是等价的,对吧?
这是正确的......但这并不意味着字节码编译器有义务为两个版本生成相同的字节码序列。
这里真正的教训是,字节码编译器生成的字节码序列几乎不会告诉您代码实际执行的方式。 您可能从读取字节码中得出的任何性能结论都是非常可疑的 。
实际上,字节码相当于中间代码。 过早优化或优化两次的ROI很低。
几乎是因为“这就是它的编写方式”。 比较考虑了左手变量并将其与右侧进行比较。 当你说null == s
,你会说“将null
与这个变量进行比较”,所以代码定义了一个null
的常量来比较。 编译器只是将其他比较优化为非空检查。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.