在学习JavaScript中的if控制语句和switch控制语句的时候,提到了使用多条件判断时switch case语句比if语句效率高,但是身为小白的我并没有在代码中看出有什么不同。去度娘找了半个小时,看了各位大神的表述,找到一个比较清晰的文章。

原来,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 }
这个就要挨着查表确定跳转位置了。

总结:在第一个例子中可以看出使用switch case的时候在匹配条件的时候是直接跳转的,所以效率相对会比if语句中逐个比较会快。而且还有一点是在switch语句中看不到的,第一个switch case语句中会首先判断case值在不在目标值中,如果不在,直接执行default,而不是逐个去比较,全部不符合条件之后再执行default。

原文出处:http://bbs.csdn.net/topics/300023354

原作者:ZangXT

 

为什么说在使用多条件判断时switch case语句比if语句效率高?的更多相关文章

  1. shell编程 条件判断式----利用 case ..... esac 判断

    条件判断式----利用 case ..... esac 判断 case  $变量名称 in   <==关键词为 case ,还有变量前有钱字号 "第一个变量内容")   &l ...

  2. if判断和switch case 和三元运算符整理

    if判断和switch case 和三元运算符整理 例子1:if判断写法: <script type="text/javascript"> var num = 12; ...

  3. js条件判断时隐式类型转换

    Javascript 中,数字 0 为假,非0 均为真 在条件判断运算 == 中的转换规则是这样的: 如果比较的两者中有布尔值(Boolean),会把 Boolean 先转换为对应的 Number,即 ...

  4. 注意了,Mybatis中条件判断时遇到的坑

    1.mapper中比较字符串时需要注意的问题如下: mybatis 映射文件中,if标签判断字符串相等,两种方式:因为mybatis映射文件,是使用的ognl表达式,所以在判断字符串isComplet ...

  5. 关于angular的ng-class条件判断

    angular的ng-class的多条件判断是非常好用的,不需要写过多的判断去更改他相应的class, 但大家要记住,在repeat中使用ng-class多条件判断时, 错误写法:<i clas ...

  6. hive:条件判断函数

    参考hive常用运算. •If函数: if •非空查找函数: COALESCE •条件判断函数:CASE • If 函数 : if 语法: if(boolean testCondition, T va ...

  7. Python基础:条件判断与循环的两个要点

    一.条件判断: Python中,条件判断用if语句实现,多个条件判断时用if...elif实现:看下面一段程序 #python 3.3.5 #test if...elif age = 20 if ag ...

  8. [译] NSScanner:一个陌生的条件判断利器!

    NSScanner官方文档 NSScanner类是一个类簇的抽象父类,该类簇为一个从NSString对象扫描值的对象提供了程序接口. NSScanner对象把NSString 对象的的字符解释和转化成 ...

  9. 10_bash_变量_条件判断及运算_sed_循环

    shell编程: 编译器.解释器编程语言:机器语言.汇编语言.高级语言 静态语言:编译型语言 强类型(变量):变量在使用前,必须事先声明,甚至还需要初始化 事先转换成可执行格式 C/C++.C#.Ja ...

随机推荐

  1. eclipse使用sublime配色(转)

    转自 Eclipse设置类似Sublime Text 编辑区皮肤,风格,颜色 1.首先打开eclipse 2.help -> Install New SoftWare  3.点击 Add 在Na ...

  2. php用redis保存session

    1.修改php.ini中session配置: ini_set('session.save_handler', 'redis');ini_set('session.save_path', 'tcp:// ...

  3. leetcode 111 minimum depth of binary tree

    problem description: Given a binary tree, find its minimum depth. The minimum depth is the number of ...

  4. 无法对 索引 'IndexName' 执行 删除,因为它不存在,或者您没有所需的权限。

    先写结论: 语法:  DROP INDEX 表名.索引名 如果索引明明存在..却报标题上那个错..请直接去看是否是表名与库中的不一样.. 请一定去检查一下..别问我为什么这么说.. if exists ...

  5. windows server 2012 使用问题

    1.端口映射,把宿主机的端口映射到hyper-v创建的虚拟机上 访问宿主机的公网IP的某个端口,就等于访问这个虚拟机上的端口 具体实现: 在宿主机上命令行输入 添加一个端口映射 netsh inter ...

  6. 关于node的http模块

    var http = require('http'); /** * 创建服务器的两种写法,第一种写法如下 * 由于server已经继承了EventEmitter的事件功能,所以可以使用高级函数编写方式 ...

  7. 20155217-杨笛-c与java

    命是弱者的借口,运是强者的谦词 你有什么技能比大多数人(超过90%以上)更好? 针对这个技能的获取你有什么成功的经验? 与老师博客中的学习经验有什么共同之处? 其实我经常会去想自己有什么拿得出手的优点 ...

  8. [老文章搬家] 关于 Huffman 编码

    按:去年接手一个项目,涉及到一个一个叫做Mxpeg的非主流视频编码格式,编解码器是厂商以源代码形式提供的,但是可能代码写的不算健壮,以至于我们tcp直连设备很正常,但是经过一个UDP数据分发服务器之后 ...

  9. Linux 下安装JRuby

    安装ruby cd git clone https://github.com/rbenv/rbenv.git ~/.rbenv echo 'export PATH="$HOME/.rbenv ...

  10. LaTeX简单使用方法

    Content LaTeX的用途 LaTeX文件布局 LaTeX的文档格式 公式环境 图的排版 表格的排版 有序列表和无序列表 引用 伪代码 参考文献 LaTeX的用途 LaTeX是一种基于TeX的排 ...