2

I am new to java development, having done python for about a year. I understand how switch statements are used when comparing a variable to multiple different values, but my question is if there are only two different values, (ie. x == 1 or x == 0) is it more optimal to use a switch statement or an if else statement? i understand how both work but I just can't figure out if there would be a difference in this case, and if there is what it would be.

  • 2
    Use whichever makes your code clearer. – khelwood Jul 12 '20 at 19:25
  • Hi Jonah, I hope you enjoy Java - personally I wouldn't worry about optimal - it is just a matter of style here - what feels more readable? It may depend on the code that is executed for each value. If there are only two possible value there is another option - possibly the most succinct - x == 1 ? doOneThing() : doOtherThing(); – Chris Jul 12 '20 at 19:26
  • 1
    This is a matter of personal preference/opinion. If you have only two options usually engineers use if/else. If you have multiple options and you compare strings/ints/enums than you can do either or. – Nir Alfasi Jul 12 '20 at 19:26
  • [What is the relative performance difference of if/else versus switch statement in Java?](https://stackoverflow.com/a/2086546/12323248) – akuzminykh Jul 12 '20 at 19:34

3 Answers3

0

If I am not wrong, switchs are slower than else/if, so that is something to know about depending on your usage.

Feche1320
  • 25
  • 1
  • 6
0

It depends. If you have only one alternative like x==4 and only two actions, I would go with an if-statement. If you have for example if(x==2||x==27||x==31){}else if(x==4||x==29||x==33){}else{} I would go with a switch statement. In this cases a switch-statement is more readable:

switch(x){
  case 2:
  case 27:
  case 31:
          foo();
          break;
  case 4:
  case 29:
  case 33:
          bar();
          break;
  default:
          throw new IllegalArgumentException("Invalid value for x: "+x);
}

From a performance POV I would say, if is faster, if there are only some cases (2-4), after that I would a switch-statement

JCWasmx86
  • 3,473
  • 2
  • 11
  • 29
0

Long story short: use whichever you like to use;

If you're interested into internals, then keep reading. We don't have to guess the answer on your question. I've written a simple example program and let's see it in the actual implementation. First I'll examine if-else, and then I'll examine switch.

If-else

public class IfElse {

    public static void main(String[] args) {

        int x = Integer.valueOf(args[0]);

        if (x==1) {
            System.out.println("x is 1");
        } else {
            System.out.println("x is not 1");
        }
    }
}

Now, after we save this in the simple text editor and compile it with javac IfElse.java, Java compiler will generate a IfElse.class file which has the following bytecode:

javap -c IfElse.class
Compiled from "IfElse.java"
public class IfElse {
  public IfElse();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: aload_0
       1: iconst_0
       2: aaload
       3: invokestatic  #2                  // Method java/lang/Integer.valueOf:(Ljava/lang/String;)Ljava/lang/Integer;
       6: invokevirtual #3                  // Method java/lang/Integer.intValue:()I
       9: istore_1
      10: iload_1
      11: iconst_1
      12: if_icmpne     26
      15: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
      18: ldc           #5                  // String x is 1
      20: invokevirtual #6                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      23: goto          34
      26: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
      29: ldc           #7                  // String x is not 1
      31: invokevirtual #6                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      34: return
}

Switch

public class Switch {

    public static void main(String[] args) {
    
        int x = Integer.valueOf(args[0]);

        switch(x) {
            case 1:
                System.out.println("x is 1");
                break;
            default:
                System.out.println("x is not 1");
        }
    }
}

in the same way, we compile it with javac Switch.java and see the bytecode afterwards:

Compiled from "Switch.java"
public class Switch {
  public Switch();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: aload_0
       1: iconst_0
       2: aaload
       3: invokestatic  #2                  // Method java/lang/Integer.valueOf:(Ljava/lang/String;)Ljava/lang/Integer;
       6: invokevirtual #3                  // Method java/lang/Integer.intValue:()I
       9: istore_1
      10: iload_1
      11: lookupswitch  { // 1
                     1: 28
               default: 39
          }
      28: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
      31: ldc           #5                  // String x is 1
      33: invokevirtual #6                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      36: goto          47
      39: getstatic     #4                  // Field java/lang/System.out:Ljava/io/PrintStream;
      42: ldc           #7                  // String x is not 1
      44: invokevirtual #6                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      47: return
}

Conclusion:

switch operator has:

  1. a bit more Java code to be written;

  2. a bit more bytecode after compilation. Namely this:

     11: lookupswitch  { // 1
             1: 28
             default: 39
         }
    
Giorgi Tsiklauri
  • 9,715
  • 8
  • 45
  • 66