请教为什么switch的效率要比if else 高? 请教为什么switch的效率要比if else 高?希望从编译原理的角度分析 谢谢哇 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 switch 只判断一次.. 就 case 了. if else 要判断很多次. 比如一个结果你要在 最后的一个 else里面.. 是不是要把前面的if全判断一遍呢? 因为一般if-else语句的情况下,每一种情况都要从开始进行比较,也就是说如果极端的情况是if-else语句的最后一种可能的话,要从头比到尾才能判断出来,而switch语句就直接到所确定的地方了,少了几个jmp,不知道是不是编译器做了优化,所以可能switch语句较快,仅仅是猜测,从来没注意过这两个的区别只是感觉switch-case可以用在简单的判断上,用if-else无论简单复杂的都可以~~ switch的case条件都是编译期整数常量,编译器可以做到表格跳转查询,查找速度快, 缺点是:case条件都是编译期整数常量 if/else是一个挨一个的查询,速度较慢, 优点是:不限比较类型和内容,你可以使用double,float,string或是自定义类型,比较双方不必是编译期常量。 switch有跳转表 是不是在switch中case少的情况下 if else会效率高点?当然分支多的情况下 这个肯定是switch比较快的。 支持LS的说法switch使用于多条件的判断switch的效率不一定就高于if else 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 }这个就要挨着查表确定跳转位置了。 写了篇blog,详细的分析了一下http://blog.csdn.net/ZangXT/archive/2009/01/14/3777897.aspx 很了好几次的这样反编译的方式去看代码,我更关心如何自己开始去用这样的方式去读,能不能谁介绍下,比方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_1iload_1是啥意思完全弄不懂, 额 企鹅兄 还是那样相当的专业啊学习ING switch 进行一次条件判断后直接执行到程序的条件语句ifelse 有几种条件,就得判断多少次ifelse和switch效率有区别,但并不能说明ifelse一无事处,有时为了可读性或者其他方面,ifelse有它的优势。 我来总结一下吧。首先大家去看看一本书《C++ Footprint and Performance Optimization》,里面的7章,第一节。然后根据大量的实际程序测试(不考虑不同的编译器优化程度差异,假设都是最好的优化),那么Switch语句击中第三个选项的时间跟if/else if语句击中第三个选项的时间相同。击中第一,第二选项的速度if语句快,击中第四以及第四之后的选项的速度switch语句快。所以,如果所有选项出现概率相同的话,结论就是:5个选项(包括default)的情况下,switch和if/else if相同。低于5个选项if快,高于5给选项switch快! 学习,不知C++和Java的处理方式是不是相同的 难道switch不是一个个比较的吗?你需要的数字也是在最后的那个case呢?难道他直接跳到最后那个case吗? 求下载ftp文件夹的源码<jdk1.6环境> 局域网游戏,如何发现建游戏的主机?类似魔兽和星际那样的。 求助:异常类处理问题 object类如何转换为整型数组! ResultSet 是一次返回所有,还是通过next一次次去连接db取? 急 一个菜鸟的URL问题 线程问题 JAVA里2个float相乘会出现精度不对 ????请问怎么在Applet应用程序中打开Word文档?????? Java实现桌面效果 java mail 附件名乱码 关于SWT组件MessageBox的国际化问题
只是感觉switch-case可以用在简单的判断上,用if-else无论简单复杂的都可以~~
缺点是:case条件都是编译期整数常量 if/else是一个挨一个的查询,速度较慢,
优点是:不限比较类型和内容,你可以使用double,float,string或是自定义类型,比较双方不必是编译期常量。
switch有跳转表 是不是在switch中case少的情况下 if else会效率高点?
当然分支多的情况下 这个肯定是switch比较快的。
switch使用于多条件的判断
switch的效率不一定就高于if else
对于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 }
这个就要挨着查表确定跳转位置了。
http://blog.csdn.net/ZangXT/archive/2009/01/14/3777897.aspx
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是啥意思完全弄不懂,
学习ING
ifelse 有几种条件,就得判断多少次
ifelse和switch效率有区别,但并不能说明ifelse一无事处,有时为了可读性或者其他方面,ifelse有它的优势。
首先大家去看看一本书《C++ Footprint and Performance Optimization》,里面的7章,第一节。然后根据大量的实际程序测试(不考虑不同的编译器优化程度差异,假设都是最好的优化),那么Switch语句击中第三个选项的时间跟if/else if语句击中第三个选项的时间相同。
击中第一,第二选项的速度if语句快,击中第四以及第四之后的选项的速度switch语句快。所以,如果所有选项出现概率相同的话,结论就是:5个选项(包括default)的情况下,switch和if/else if相同。低于5个选项if快,高于5给选项switch快!
难道switch不是一个个比较的吗?你需要的数字也是在最后的那个case呢?难道他直接跳到最后那个case吗?