2

I was wondering would there be a performance differences while i use logical operators instead of several if statements. I saw a nice link, does this apply to java also?

4
  • 2
    do you mean: if(a) if(b) if(c) d(); versus if(a && b && c) d();? Commented Jul 26, 2012 at 20:45
  • I kind of doubt that it does, but there are serveral byte code inspection tools for java if you're really curious. You can also write a really big loop and compare the performance. Commented Jul 26, 2012 at 20:47
  • 3
    I would assume it would be negligible, if it existed at all, but why don't you test it? Commented Jul 26, 2012 at 20:47
  • 2
    The article you posted gives an excellent example of how to test this. Just stick a timer on it and compare the speeds. Commented Jul 26, 2012 at 20:49

3 Answers 3

4

I just created class like

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

compiled it then decompiled by javap -c Test and got these result

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
}

As you can see bytecodes of test1 and test2 are same, so there is no difference in using

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

or

    if (test())
        if (test()) 
            if (test())
Sign up to request clarification or add additional context in comments.

1 Comment

It means that the two ways of writing the code compile to the same bytecode. There is no optimization involved. There's just no other sensible way to compile &&.
0

It's implementation dependent - so you'll need to benchmark to be sure.

Having said that, most JIT compilers are smart enough to optimise boolean comparisons very effectively so you are unlikely to see any difference.

The only area where logical operators are likely to offer a substantial advantage are in cases where you are using them to perform bitwise computations. This can be very efficient since it can result in branchless code that exploits hardware instructions.

5 Comments

How is it implementation dependent? And logical operators are not bitwise operators: these are just two different things.
It's implementation dependent because the Java compiler and/or JIT compiler may or may not choose to optimise these down to the most efficient bytecode / machine code respectively. You have no guarantees. And it may be a matter of definitions but bitwise operations are just logical operations applied to bit vectors rather than booleans, so it's common to consider them as similar.
Really. How else can you compile &&? And bitwise operators are completely different beasts, as they don't short-circuit. Which is what the question is about, so they aren't even relevant.
The question isn't about short-circuiting operators specifically. But even if it was, then a bitwise op is the efficient way to compile && in any situation where the left hand argument is available in a local variable or register, since it's faster to do a bitwise op with a local value than to put in an extra branch. The only case where you need a branch with a short-circuiting operator is when there are side effects, in all other cases the compiler is free to decide whether or not it would be faster to evaluate the left hand side anyway and use a bitwise op (it produces the same result)
So that we can all agree please tell us which Java compilers behave as you describe.
0

Both forms compile to the same code. Contrary to the suggestions in other answers, this is not an 'optimization', and it would be astonishing if different compilers did different things. There is only one sensible way to compile && and that is by treating it the same as another 'if'. I can't even think of a non-sensible way.

1 Comment

Prepare then to be astonished then - different compilers do wildly different things even in supposedly "simple" cases. Also an extra if branch would often be an inefficient way to compile a logical operator - these can be more efficiently implemented with a bitwise instruction in many situations because the branch mis-prediction penalty is much higher than the cost of a bitwise op.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.