当有很多个case时,switch是怎样做到只要少数比较(只要1次?)就得出结果的?
就算有个跳转表也是需要经过多次的比较才可以找到相应的位置的不是吗?毕竟是dumb computer,当没有给一个明确的指令时,只有通过不断的比较才可以得到结果。
例如SQL的索引,索引的原理和switch差不多吧,只是原理到底是什么?
当有很多个case时,switch是怎样做到只要少数比较(只要1次?)就得出结果的?
就算有个跳转表也是需要经过多次的比较才可以找到相应的位置的不是吗?毕竟是dumb computer,当没有给一个明确的指令时,只有通过不断的比较才可以得到结果。
例如SQL的索引,索引的原理和switch差不多吧,只是原理到底是什么?
我猜测,首先Switch底层是:Label + Goto
至于判断部分略过goto 1
Label 1:
xxx
如果是字符串:
case "1"-->编译时进行参数转换-->goto 0xa12112,同时动态传入的参数Switch(a)中a会转化为0xa12112这个Key,通过这个Key查询HashTable,从而确定goto语句是否存在,不存在就执行default
goto 0xa12112
Label 0xa12112:
xxx
关于跳转表的原理我大概理解了,谢谢各位的回答。原理是通过数组下标来跳转,当然如果case的值相差过大又没规律可能会采用以if为主的二分查找方法(数学真是伟大。)大概sql的索引也是相似的原理。
ps:附上两篇Google找到的关于跳转表的文章
http://www.programlife.net/sw...
http://www.voidcn.com/blog/si...。
先不说JavaScript的情况。就C/C++和Java而言,case跟的必须是常量,这就为编译优化带来了空间。
至于编译器是如何优化的(JVM暂且不说),写一段C语言的程序,编译时输出汇编语言,看下就知道了。
另外,Java 1.7+支持switch String,我猜原理可能跟HashTable类似吧。
10 回答11.1k 阅读
15 回答8.4k 阅读
6 回答3k 阅读
5 回答4.8k 阅读✓ 已解决
4 回答3.1k 阅读✓ 已解决
8 回答6.2k 阅读
2 回答2.6k 阅读✓ 已解决
我们可以直接通过汇编代码来看:
汇编其中关键代码如下:可以看到case实际的比较顺序是2->3->1, 并不是代码的编写顺序:
至于为什么是这个顺序,没有研究过,这是编译器层面的处理了,可以一起学习下,
第二次修改
@felix ,这里上面特意没有开启优化,因为是要看原理,所以优化就没有什么意思,下面是开始O2选项的结果:
下面是rodata中保存的要输出的“case 1”字符串, 在不优化的情况下,rodata中是会有"case 2" , "case 3", "default case"的。
第三次修改
@felix ,谢谢, 当case语句增加到10条(具体多少开启,可以测一下)时,编译器(debug和O2)开启了case 的匹配优化,也就是大家所谓的jump table: