请教为什么switch的效率要比if else 高?希望从编译原理的角度分析  谢谢哇

解决方案 »

  1.   

    switch 只判断一次.. 就 case 了.          if else 要判断很多次.  比如一个结果你要在 最后的一个 else里面.. 是不是要把前面的if全判断一遍呢?
      

  2.   

    因为一般if-else语句的情况下,每一种情况都要从开始进行比较,也就是说如果极端的情况是if-else语句的最后一种可能的话,要从头比到尾才能判断出来,而switch语句就直接到所确定的地方了,少了几个jmp,不知道是不是编译器做了优化,所以可能switch语句较快,仅仅是猜测,从来没注意过这两个的区别
    只是感觉switch-case可以用在简单的判断上,用if-else无论简单复杂的都可以~~
      

  3.   

    switch的case条件都是编译期整数常量,编译器可以做到表格跳转查询,查找速度快, 
    缺点是:case条件都是编译期整数常量 if/else是一个挨一个的查询,速度较慢, 
    优点是:不限比较类型和内容,你可以使用double,float,string或是自定义类型,比较双方不必是编译期常量。
      

  4.   


    switch有跳转表 是不是在switch中case少的情况下 if else会效率高点?
    当然分支多的情况下  这个肯定是switch比较快的。
      

  5.   

    支持LS的说法
    switch使用于多条件的判断
    switch的效率不一定就高于if else
      

  6.   

    switch可以进行跳转优化,java中对switch有两种处理方式,生成不同的jvm指令,一是tableswitch,一个是lookupswitch.
    对于case的分支比较密集的情况,如public class Test {    public static void main(String[] args) {
            int i = 3;
            switch (i) {
                case 0:
                    System.out.println("0");
                    break;
                case 1:
                    System.out.println("1");
                    break;
                case 3:
                    System.out.println("3");
                    break;
                case 5:
                    System.out.println("5");
                    break;
                case 10:
                    System.out.println("10");
                    break;
                case 13:
                    System.out.println("13");
                    break;
                case 14:
                    System.out.println("14");
                    break;
        default:
    System.out.println("default");
                    break;
            }
        }
    }使用tableswitch,得到public static void main(java.lang.String[]);
      Code:
       0: iconst_3
       1: istore_1
       2: iload_1
       3: tableswitch{ //0 to 14
    0: 76;
    1: 87;
    2: 153;
    3: 98;
    4: 153;
    5: 109;
    6: 153;
    7: 153;
    8: 153;
    9: 153;
    10: 120;
    11: 153;
    12: 153;
    13: 131;
    14: 142;
    default: 153 }
       76: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
       79: ldc #3; //String 0
       81: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
       84: goto 161
       87: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
       90: ldc #5; //String 1
       92: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
       95: goto 161
       98: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
       101: ldc #6; //String 3
       103: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
       106: goto 161
       109: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
       112: ldc #7; //String 5
       114: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
       117: goto 161
       120: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
       123: ldc #8; //String 10
       125: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
       128: goto 161
       131: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
       134: ldc #9; //String 13
       136: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
       139: goto 161
       142: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
       145: ldc #10; //String 14
       147: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
       150: goto 161
       153: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
       156: ldc #11; //String default
       158: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
       161: return}从中可以看到tableswitch使用的跳转表。它这样查找,如果case值不在//0 to 14之间,直接执行default,如果在此范围之内,则取目标值-0这一项作为目标,比如switch(i),i为3,则跳转到3-0=3,使用数组中的第三项作为目标,也就是3: 98;直接去执行98行。如果case中的值比较稀疏,则使用lookupswitch:public class Test2 {    public static void main(String[] args) {
            int i = 3;
            switch (i) {
                case 3:
                    System.out.println("3");
                    break;
                case 20:
                    System.out.println("20");
                    break;
                case 50:
                    System.out.println("50");
                    break;
                case 100:
                    System.out.println("100");
                    break;
            }
        }
    }编译为public static void main(java.lang.String[]);
      Code:
       0: iconst_3
       1: istore_1
       2: iload_1
       3: lookupswitch{ //4
    3: 44;
    20: 55;
    50: 66;
    100: 77;
    default: 85 }
       44: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
       47: ldc #3; //String 3
       49: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
       52: goto 85
       55: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
       58: ldc #5; //String 20
       60: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
       63: goto 85
       66: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
       69: ldc #6; //String 50
       71: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
       74: goto 85
       77: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
       80: ldc #7; //String 100
       82: invokevirtual #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
       85: return
    可以看到其中的
     3: lookupswitch{ //4
    3: 44;
    20: 55;
    50: 66;
    100: 77;
    default: 85 }
    这个就要挨着查表确定跳转位置了。
      

  7.   

    写了篇blog,详细的分析了一下
    http://blog.csdn.net/ZangXT/archive/2009/01/14/3777897.aspx
      

  8.   

    很了好几次的这样反编译的方式去看代码,我更关心如何自己开始去用这样的方式去读,能不能谁介绍下,比方
    0:    iconst_3
       1:    istore_1
       2:    iload_1
       3:    lookupswitch{ //4
            3: 44;
            20: 55;
            50: 66;
            100: 77;
            default: 85 }
       44:    getstatic    #2; //Field java/lang/System.out:Ljava/io/PrintStream;
       47:    ldc    #3; //String 3
    这样的,istore_1
    iload_1是啥意思完全弄不懂,
      

  9.   

    额 企鹅兄 还是那样相当的专业啊
    学习ING
      

  10.   

    switch 进行一次条件判断后直接执行到程序的条件语句
    ifelse 有几种条件,就得判断多少次
    ifelse和switch效率有区别,但并不能说明ifelse一无事处,有时为了可读性或者其他方面,ifelse有它的优势。
      

  11.   

    我来总结一下吧。
    首先大家去看看一本书《C++ Footprint and Performance Optimization》,里面的7章,第一节。然后根据大量的实际程序测试(不考虑不同的编译器优化程度差异,假设都是最好的优化),那么Switch语句击中第三个选项的时间跟if/else if语句击中第三个选项的时间相同。
    击中第一,第二选项的速度if语句快,击中第四以及第四之后的选项的速度switch语句快。所以,如果所有选项出现概率相同的话,结论就是:5个选项(包括default)的情况下,switch和if/else if相同。低于5个选项if快,高于5给选项switch快!
      

  12.   

    学习,不知C++和Java的处理方式是不是相同的
      

  13.   


    难道switch不是一个个比较的吗?你需要的数字也是在最后的那个case呢?难道他直接跳到最后那个case吗?