【发布时间】:2014-12-18 17:03:49
【问题描述】:
java编译器会优化这个吗:
boolean foo1 = getSomeHardToGetBoolean();
boolean foo2 = getSomeEasyToGetBoolean();
if(foo1 && foo2){
//do stuff
}
到这里:
if(getSomeEasyToGetBoolean() && getSomeHardToGetBoolean()){
//do stuff
}
甚至这个:
if(getSomeHardToGetBoolean() && getSomeEasyToGetBoolean()){
//do stuff
}
我将第一种方法用作可读性的一般做法,但代价是什么?
旁注:假定为 Java 8。使用 JIT。直到运行时才能确定布尔值。布尔值彼此完全独立。我可能不会停止使用第一种方式,但我只是好奇。谢谢!
【问题讨论】:
-
如果您不每秒执行数千次,性能成本可以忽略不计。过早的优化是万恶之源。
-
您指的是哪个编译器(javac 还是 JIT)?
foo1和foo2是否是“常数”,即使它们不是 JLS 的正式常数?您能否详细说明其中的内容?为什么不期望它一直优化到if (false),然后删除死代码?如果您担心性能,请注意即使优化器不处理它,这对于分支预测器来说也很容易。 -
写微基准。运行百万次后,您将看到它是否得到了优化。
-
一个好的优化器会将
if (foo1 && foo2);优化为一个空语句,因为无论条件是真还是假,你的代码都不会做任何事情。另一方面,如果您在if之后有一个实际语句或块而不是分号,这是一个更有趣的问题。 -
@Evorlor 也许吧。理论上,编译器可以跟踪方法可能产生的副作用。在实践中,如果您希望您的程序在一年内完成编译,那么优化器可以做的事情是有限度的。如果
getSomeEasyToGetBoolean足够简单,那是可能的。但是确定任何特定编译器的唯一方法是尝试它。语言本身并没有指定这些内容。
标签: java compiler-optimization