【问题标题】:Short circuit evaluation should be faster than bitwise evaluation, but it is not. Why? [duplicate]短路评估应该比按位评估更快,但事实并非如此。为什么? [复制]
【发布时间】:2018-09-25 02:19:52
【问题描述】:

为了比较短路求值逻辑运算符(例如&&)与位求值逻辑运算符(即&)的执行情况,我编写了这个示例并运行它:

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();
    }
}

一个示例运行显示如下:

java examples1/ShortCircuitOperatorsVSBitwiseOperators
Enter A: false
Enter B: true
false in 4829 milliseconds, short-circuited
false in 3276 milliseconds, bitwise

这没有意义。我希望短路评估会更快,因为在这种情况下,如果左侧是false,它不会评估&amp;&amp; 的右侧。反直觉结果的原因是什么?

【问题讨论】:

  • 问得好,但两个性能数据似乎相似。你检查过它是否可以重现吗?另外,更小/更大的循环会发生什么?
  • 是的,它是可重现的。对于较小的循环,短路评估仍然较慢,就像较大的循环一样。
  • 恭喜,您创建的微基准测试不正确。只需改变这两个操作的顺序(先按位,然后短路),你会得到相反的结果。这是因为 Java 启动时间、HotSpot 编译和许多其他因素。
  • 微基准测试很难。我建议您将 JMH 视为正确微基准测试的框架。 stackoverflow.com/questions/504103/…
  • @ErwinBolwidt 我确实根据您的评论更改了顺序,短路评估仍然比按位慢。这是我第一次听说微基准测试的概念,所以无论如何都值得一看。谢谢。

标签: java bitwise-operators logical-operators short-circuiting


【解决方案1】:

短路操作很复杂。

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

【讨论】:

  • 那么,如果在按位求值(与 OP 进行测试的顺序相反)之后进行短路求值,为什么会花费更少的时间?
  • @ErwinBolwidt 我不知道为什么。这不是OP的问题。如果您想知道原因,您应该发布自己的问题。
  • 我问你这个问题是为了让你意识到你发布的内容并没有回答 OP 的问题。字节码指令的数量与执行速度的关系很小;如果您交换测试的顺序,那么具有更多字节码指令的测试执行得更快。
  • 如果是这样请不要问我。 SO 不是一个测试人的网站。
猜你喜欢
  • 2013-10-18
  • 1970-01-01
  • 2011-10-11
  • 2015-11-02
  • 2013-02-01
  • 2015-11-14
  • 2017-01-21
  • 2012-02-10
  • 2010-12-21
相关资源
最近更新 更多