2

我想知道当我使用逻辑运算符而不是几个 if 语句时是否会有性能差异。我看到了一个不错的链接,这也适用于 java 吗?

4

3 回答 3

4

我刚刚创建了类

class Test{
    static java.util.Random r=new java.util.Random();
    boolean test(){
        return r.nextBoolean();
    }
    void test1(){
        if (test() && test() && test())
            System.out.println("3x yes");
    }
    void test2(){
        if (test())
            if (test()) 
                if (test())
                    System.out.println("3x yes");
    }
}

编译它然后通过javap -c Test反编译并得到这些结果

class Test {
  static java.util.Random r;

  Test();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":
()V
       4: return

  boolean test();
    Code:
       0: getstatic     #2                  // Field r:Ljava/util/Random;
       3: invokevirtual #3                  // Method java/util/Random.nextBoole
an:()Z
       6: ireturn

  void test1();
    Code:
       0: aload_0
       1: invokevirtual #4                  // Method test:()Z
       4: ifeq          29
       7: aload_0
       8: invokevirtual #4                  // Method test:()Z
      11: ifeq          29
      14: aload_0
      15: invokevirtual #4                  // Method test:()Z
      18: ifeq          29
      21: getstatic     #5                  // Field java/lang/System.out:Ljava/
io/PrintStream;
      24: ldc           #6                  // String 3x yes
      26: invokevirtual #7                  // Method java/io/PrintStream.printl
n:(Ljava/lang/String;)V
      29: return

  void test2();
    Code:
       0: aload_0
       1: invokevirtual #4                  // Method test:()Z
       4: ifeq          29
       7: aload_0
       8: invokevirtual #4                  // Method test:()Z
      11: ifeq          29
      14: aload_0
      15: invokevirtual #4                  // Method test:()Z
      18: ifeq          29
      21: getstatic     #5                  // Field java/lang/System.out:Ljava/
io/PrintStream;
      24: ldc           #6                  // String 3x yes
      26: invokevirtual #7                  // Method java/io/PrintStream.printl
n:(Ljava/lang/String;)V
      29: return

  static {};
    Code:
       0: new           #8                  // class java/util/Random
       3: dup
       4: invokespecial #9                  // Method java/util/Random."<init>":
()V
       7: putstatic     #2                  // Field r:Ljava/util/Random;
      10: return
}

如您所见test1test2的字节码相同,因此使用没有区别

    if (test() && test() && test())

或者

    if (test())
        if (test()) 
            if (test())
于 2012-07-26T21:00:58.947 回答
0

它取决于实现 - 因此您需要确定基准。

话虽如此,大多数 JIT 编译器都足够聪明,可以非常有效地优化布尔比较,因此您不太可能看到任何差异。

逻辑运算符可能提供显着优势的唯一领域是您使用它们执行按位计算的情况。这可能非常有效,因为它可能导致利用硬件指令的无分支代码。

于 2012-07-26T20:57:40.687 回答
0

两种形式都编译为相同的代码。与其他答案中的建议相反,这不是“优化”,如果不同的编译器做了不同的事情,那将是令人惊讶的。编译 && 只有一种明智的方法,那就是将其与另一个“if”相同。我什至想不出一个不明智的方法。

于 2012-07-27T01:37:45.673 回答