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