为什么说在使用多条件判断时switch case语句比if语句效率高?
在学习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语句效率高?的更多相关文章
- shell编程 条件判断式----利用 case ..... esac 判断
条件判断式----利用 case ..... esac 判断 case $变量名称 in <==关键词为 case ,还有变量前有钱字号 "第一个变量内容") &l ...
- if判断和switch case 和三元运算符整理
if判断和switch case 和三元运算符整理 例子1:if判断写法: <script type="text/javascript"> var num = 12; ...
- js条件判断时隐式类型转换
Javascript 中,数字 0 为假,非0 均为真 在条件判断运算 == 中的转换规则是这样的: 如果比较的两者中有布尔值(Boolean),会把 Boolean 先转换为对应的 Number,即 ...
- 注意了,Mybatis中条件判断时遇到的坑
1.mapper中比较字符串时需要注意的问题如下: mybatis 映射文件中,if标签判断字符串相等,两种方式:因为mybatis映射文件,是使用的ognl表达式,所以在判断字符串isComplet ...
- 关于angular的ng-class条件判断
angular的ng-class的多条件判断是非常好用的,不需要写过多的判断去更改他相应的class, 但大家要记住,在repeat中使用ng-class多条件判断时, 错误写法:<i clas ...
- hive:条件判断函数
参考hive常用运算. •If函数: if •非空查找函数: COALESCE •条件判断函数:CASE • If 函数 : if 语法: if(boolean testCondition, T va ...
- Python基础:条件判断与循环的两个要点
一.条件判断: Python中,条件判断用if语句实现,多个条件判断时用if...elif实现:看下面一段程序 #python 3.3.5 #test if...elif age = 20 if ag ...
- [译] NSScanner:一个陌生的条件判断利器!
NSScanner官方文档 NSScanner类是一个类簇的抽象父类,该类簇为一个从NSString对象扫描值的对象提供了程序接口. NSScanner对象把NSString 对象的的字符解释和转化成 ...
- 10_bash_变量_条件判断及运算_sed_循环
shell编程: 编译器.解释器编程语言:机器语言.汇编语言.高级语言 静态语言:编译型语言 强类型(变量):变量在使用前,必须事先声明,甚至还需要初始化 事先转换成可执行格式 C/C++.C#.Ja ...
随机推荐
- C#技术漫谈之垃圾回收机制(GC)
GC的前世与今生 虽然本文是以.NET作为目标来讲述GC,但是GC的概念并非才诞生不久.早在1958年,由鼎鼎大名的图林奖得主John McCarthy所实现的Lisp语言就已经提供了GC的功能,这是 ...
- swift3.0变化总结
Swift 3.0 做出的改变很大,在这篇文章中,我将尽我所能,利用代码样例给大家解释Swift 3.0最重要(要命)的改变,希望大家能够做好升级Swift 3.0 的准备.Swift 3.0的改变不 ...
- php中引用&的真正理解-变量引用、函数引用、对象引用
php的引用(就是在变量或者函数.对象等前面加上&符号) //最重要就是 删除引用的变量 ,只是引用的变量访问不了,但是内容并没有销毁 在PHP 中引用的意思是:不同的名字访问同一个变量内容. ...
- CMakeLists.txt
vtkRendering.libvtkCommon.lib ${VTK_LIBRARIES} vtkRendering vtkCommon
- mysql基于“时间”的盲注
无需页面报错,根据页面响应时间做判断! mysql基于时间的盲注 =================================================================== ...
- 类别(Category)与扩展(Extensions)
一.类别(Category) 类别(Category)是一种可以为现有的类(包括类簇:NSString...,甚至源码无法获得的类)添加新方法的方式无需从现有的类继承子类.类别添加的新方法可以被子类继 ...
- Eclipse常用快捷键汇总
经常使用eclipse进行开发,不掌握快捷键步行啊,在此整理了一些快捷键,大家要灵活运用啊... (注:红色标出来的是经常使用到的快捷键,磨刀不误砍柴工啊...) Ctrl+1 快速修复(最经典的快捷 ...
- 常用ubuntu命令
解压缩.7z sudo apt-get install p7zip-full 7z x PACKAGE.7z 查看图片 eog A.png 关闭打开触摸板(触点) sudo rmmod psmouse ...
- 为什么要用base64编码
1.需求 了解为什么要使用base64对数据编码 2.理由 因为传输二进制数据的时候,网络中间的有些路由会把ascii码中的不可见字符删了,导致数据不一致.一般也会对url进行base64编码 Whe ...
- 购物车相关 js
<div class="caigou"> <form action="" method="post"> <di ...