Java 短路评估应该比按位评估快,但事实并非如此。为什么?
为了比较短路评估逻辑运算符(例如Java 短路评估应该比按位评估快,但事实并非如此。为什么?,java,bitwise-operators,logical-operators,short-circuiting,Java,Bitwise Operators,Logical Operators,Short Circuiting,为了比较短路评估逻辑运算符(例如&)与按位评估逻辑运算符(即&)的执行情况,我编写了这个示例并运行了它: package examples1; import java.util.Scanner; public class ShortCircuitOperatorsVSBitwiseOperators { public static void main(String[] args) { Scanner scanner = new Scanner(System.in);
&
)与按位评估逻辑运算符(即&
)的执行情况,我编写了这个示例并运行了它:
package examples1;
import java.util.Scanner;
public class ShortCircuitOperatorsVSBitwiseOperators {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter A: "); boolean a = scanner.nextBoolean();
System.out.print("Enter B: "); boolean b = scanner.nextBoolean();
long startTimeShortCircuited = System.currentTimeMillis();
boolean resultShortCircuited = true;
for(long i = 0; i < 10000000000L; i++) {
resultShortCircuited = a && b;
}
long endTimeShortCircuited = System.currentTimeMillis();
System.out.println(resultShortCircuited + " in " + (endTimeShortCircuited - startTimeShortCircuited) + " milliseconds, short-circuited");
long startTimeBitwise = System.currentTimeMillis();
boolean resultBitwise = true;
for(long i = 0; i < 10000000000L; i++) {
resultBitwise = a & b;
}
long endTimeBitwise = System.currentTimeMillis();
System.out.println(resultBitwise + " in " + (endTimeBitwise - startTimeBitwise) + " milliseconds, bitwise");
scanner.close();
}
}
这没有道理。我希望短路评估会更快,因为如果左侧为
false,它不会评估&&
的右侧。产生反直觉结果的原因是什么?短路操作很复杂
public static boolean shortCircuitedAnd(boolean a, boolean b) {
return a && b;
}
public static boolean bitwiseAnd(boolean a, boolean b) {
return a & b;
}
它们被编译为
public static boolean shortCircuitedAnd(boolean, boolean);
Code:
0: iload_0
1: ifeq 10
4: iload_1
5: ifeq 10
8: iconst_1
9: ireturn
10: iconst_0
11: ireturn
public static boolean bitwiseAnd(boolean, boolean);
Code:
0: iload_0
1: iload_1
2: iand
3: ireturn
好问题,但两个性能数据似乎相似。你检查过它是否可以复制吗?此外,更小/更大的回路会发生什么?是的,它是可复制的。对于较小的回路,短路评估仍然较慢,对于较大的回路也是如此。祝贺您,您创建了一个错误的微基准。只需更改两个操作的顺序(先按位执行,然后短路),您就会得到相反的结果。这是因为Java启动时间、热点编译和许多其他因素。我建议您将JMH视为正确的微基准的框架@ErwinBolwidt我确实根据您的评论更改了顺序,短路计算仍然比按位计算慢。这是我第一次听说微基准标记的概念,因此无论怎样都值得一看。谢谢。那么,如果在按位计算之后进行短路计算(与OP进行测试的顺序相反),为什么短路计算花费的时间更少呢?@ErwinBolwidt我不知道为什么。这不是OP的问题。如果你想知道为什么,你应该把自己的问题贴出来。我问你这个问题是为了让你意识到你贴出来的东西并不能回答OP的问题。字节码指令的数量与执行速度的关系很小;如果您交换测试顺序,那么具有更多字节码指令的测试执行得更快。如果是这样,请不要问我。所以不是一个测试人的网站。
public static boolean shortCircuitedAnd(boolean, boolean);
Code:
0: iload_0
1: ifeq 10
4: iload_1
5: ifeq 10
8: iconst_1
9: ireturn
10: iconst_0
11: ireturn
public static boolean bitwiseAnd(boolean, boolean);
Code:
0: iload_0
1: iload_1
2: iand
3: ireturn