Java: Performance of Enums vs. if-then-else

后端 未结 6 1743

I\'ve had no real luck getting a concise answer for this comparison by using Google and rather than do my own time consuming evaluations, I thought I would ask first.

<
相关标签:
6条回答
  • 2020-12-17 21:03

    Yes, a switch statement will pretty much always execute faster than the equivalent block of if / else statements because the compiler can perform more optimisations (typically a switch block becomes compiled down to a branch table which is pretty much impossible to do with a block of conditionals.)

    I'd say they're also both more readable and more maintainable (with the exception of using fall-through cases which I'd advise against!)

    As to whether it's noticeably faster, it depends what you define as noticeable. Chances are unless you're after something really specific you won't notice it at all, but I'd still do things this way because of the readability advantage more than anything else (treat the speed advantage as a bonus!)

    0 讨论(0)
  • 2020-12-17 21:06

    My answer to this is the same as always to question is language construct X generally faster than language construct Y: There is no general answer!

    There may be only specific answer for certain implementations of a language, e.g. Oralce's (formally Sun's) Hotspot-compiler based JVM or for an IBM JDK on plattform Z or for an OpenJDK on Linux, or...

    So, the only way to give a meaningfull answer to your question is to do a proper benchmark. Beware of micro benchmarks, they are more often wrong than right, see e.g. How not to write a micro benchmark. If you still want to find about use this question framework described here.

    Therfore, I would advise to select language feature by their applicability and readibility in your context.

    0 讨论(0)
  • 2020-12-17 21:11

    Yeap, it does, because in general term a switch statement works faster than if/else chain.

    Although bytecode generated is not always definitive source for performance comparisons you can examine it to have a better idea.

    For instance this code:

    class A { 
        enum N { ONE, TWO, THREE }
        void testSwitch( N e ) { 
            switch( e ) { 
                case ONE : x(); break;
                case TWO : x(); break;
                case THREE : x(); break;
            }
        }
        void testIf( Enum e ) { 
            if( e == N.ONE ) { x(); }
            else if( e == N.TWO ) { x(); }
            else if( e == N.THREE ) { x(); }
        }
        void x(){}
    }
    

    Generates the following:

    Compiled from "A.java"
    class A extends java.lang.Object{
    A();
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
       4:   return
    
    void testSwitch(A$N);
      Code:
       0:   getstatic   #2; //Field A$1.$SwitchMap$A$N:[I
       3:   aload_1
       4:   invokevirtual   #3; //Method A$N.ordinal:()I
       7:   iaload
       8:   tableswitch{ //1 to 3
            1: 36;
            2: 43;
            3: 50;
            default: 54 }
       36:  aload_0
       37:  invokevirtual   #4; //Method x:()V
       40:  goto    54
       43:  aload_0
       44:  invokevirtual   #4; //Method x:()V
       47:  goto    54
       50:  aload_0
       51:  invokevirtual   #4; //Method x:()V
       54:  return
    
    void testIf(java.lang.Enum);
      Code:
       0:   aload_1
       1:   getstatic   #5; //Field A$N.ONE:LA$N;
       4:   if_acmpne   14
       7:   aload_0
       8:   invokevirtual   #4; //Method x:()V
       11:  goto    39
       14:  aload_1
       15:  getstatic   #6; //Field A$N.TWO:LA$N;
       18:  if_acmpne   28
       21:  aload_0
       22:  invokevirtual   #4; //Method x:()V
       25:  goto    39
       28:  aload_1
       29:  getstatic   #7; //Field A$N.THREE:LA$N;
       32:  if_acmpne   39
       35:  aload_0
       36:  invokevirtual   #4; //Method x:()V
       39:  return
    
    void x();
      Code:
       0:   return
    
    }
    

    Which seems to be pretty fast in both cases.

    So, pick the one that is easier to maintain.

    0 讨论(0)
  • 2020-12-17 21:20

    Just stick with the most readable and clear to understand code you can come up with, I'm sure you lost all the time gained in the performance optimization while looking for this answer already. Micro-optimizations like this rarely are worth it and can easily result in code that's more complex than needed.

    0 讨论(0)
  • 2020-12-17 21:21

    In theory a switch statement can be optimised as a single calculated jump, whereas if-then-else chains have to remain as individual comparisons. I don't know whether Java actually performs this optimisation though.

    Regardless, switches are better than if-then-else chains in terms of readability and maintainability, so use them anyway if possible.

    0 讨论(0)
  • 2020-12-17 21:22

    I don't know about faster, I'd guess they are both blazingly fast.

    My consideration is that switch with enums is a lot more readable than a multi-if/else block

    But beware of missing break statements!!

    0 讨论(0)
提交回复
热议问题