提问: ifelse 语句和 switch 语句,除了 if 可以更加具体的判断外,两者还有什么区别呢,各自在什么情况下使用更好
1
hyd8323268 OP 刚刚看了看博客说 switch 会比 if 效率更好点,但是具体为什么好呢,好多少
|
2
kzfile 2019-06-25 10:26:52 +08:00
我好像在一些地方看到推荐用 if/else 替换 switch
|
3
chendy 2019-06-25 10:33:52 +08:00
有的语言(我只知道 kotlin ),case 里可以放条件判断,效果相当于一串 if-else-if
不考虑这个,switch 在一些情况下性能比一串判断好,毕竟只有一次判断,ifelse 可能要判断很多次才能走到复合条件的分支 最后其实还是“具体情况具体分析”,用哪种写起来清晰已读就用哪种 |
4
hyd8323268 OP if 语句会从第一个判断开始,挨个过,直到满足条件。而 switch 会创建一个类似数组的东西,然后把每个 case 内的条件放入,如果需要判断的值是数字,则去判断数组中最大值是否大于变量,小于则直接走 default,如果大于则再走指定 case。
大概是这样吗 |
5
misaka19000 2019-06-25 10:35:57 +08:00
这个问题,要具体语言具体分析
|
6
annielong 2019-06-25 10:53:13 +08:00 1
反正个人用的时候判断条件超过 3 个就使用 switch,不超过就用 if
|
7
glishijie 2019-06-25 11:10:41 +08:00 via Android
不同语言语义是不同的,c 语言 case 只能是常数值,不能是表达式,switch 实现的时候通常会有 switch table,可以减小 cache Miss,性能会好一点
|
8
cnzjl 2019-06-25 11:14:59 +08:00
使用 switch..case 应该是更好维护点,你想想 10 个条件在那使用 if...else,然后 switch 的匹配好像是随机的吧,确定了选择值就直接跳过去了,如果是 if 的话就要一步一步走下去,条件多的时候还是推荐 switch
|
9
shendaowu 2019-06-25 11:29:04 +08:00 1
switch 在一定条件下时间复杂度好像可以达到 O(1)。有兴趣可以搜搜“查表法”。这篇好像不错: https://www.jianshu.com/p/3efd6ca8011f。switch 在某些条件下应该是可以优化成类似查表法的东西,我不太确定。楼主如果懂汇编语言的话写一些不同的 switch 语句然后看汇编代码会很好玩的。我之前好像就是在看汇编代码的时候发现 switch 和 if 的区别的。
|
10
shendaowu 2019-06-25 11:29:34 +08:00
|
11
pkookp8 2019-06-25 11:30:12 +08:00 via Android
什么语言
试了下 c 语言,x86 的 gcc,差了一条指令 对 x86 汇编不太熟还没仔细看 |
12
shawndev 2019-06-25 11:30:18 +08:00
有模式匹配的语言,switch case 表达力更强。没有模式匹配的语言,多数情况下 switch case 可以使用表驱动法开发。
|
13
xuanbg 2019-06-25 11:31:03 +08:00
if()需要按顺序一个个 else if()进行判断执行代码块还是跳出,switch 直达条件所在代码块执行。所以只有一个 if/else 两者没区别,else if 越多区别越大。当然,switch 虽好,不符合条件也是用不了的。
|
14
xuanbg 2019-06-25 11:36:01 +08:00
@chendy case 里可以放条件判断,效果并不是相当于一串 if-else-if。case 里的条件只是第二次 match 罢了,不成功就结束了,不会再去 match 下一个 case
|
15
dangyuluo 2019-06-25 11:37:36 +08:00
现代编译器足够聪明,在条件不造成其他影响的情况下,能够自动将二者转换,挑选效率最高的那个,放心交给编译器去做就可以了,实在害怕可以看一下出来的汇编代码。
当然你也可以添加分支预测语句`likely(xxx)`,不过一般这时候你也成大牛了。 |
16
wysnylc 2019-06-25 12:27:12 +08:00
在 java 中 if else if else 是从上往下逐个匹配,在上百个判断时效率极低,此时 switch 可以站出来了因为时间复杂度是 O(1)
然后还有一种是使用 treeMap 可以做范围条件匹配,简单讲是能用 switch 和 treeMap 就用不行再考虑 if else |
17
maokabc 2019-06-25 12:42:00 +08:00 via Android
其他不清楚,java 整数 switch 的话会被编译为 table-switch 或者 lookup-switch,对应查表法和二分法
|
18
Shy07 2019-06-25 12:54:59 +08:00
弱类型的建议用 if else 严格判断
switch 建议用 hash/array/map/object + closure 的方式更 FP |
19
ragnaroks 2019-06-25 13:45:17 +08:00
if 可以对应多个判断项,比如`object1!=null && object1.value1 is Int32`,不过如果是 C#的话,7+以上区别不大了,switch 也可以匹配多个表达式
|
20
springmarker 2019-06-25 14:06:36 +08:00
一个是静态的,一个是动态的
|
21
yedanten 2019-06-25 15:07:21 +08:00
可以写个小 demo,然后逆向一下就知道了。这里写两个 demo 给 LZ 解释一下。
两个 demo 编译都是采用 gcc -O0 的方式 先看 if 的,代码如下。 ![ifcode]( https://imgur.com/3Nc8Nzl) 在看逆向之后的结果 ![ifreverse]( https://imgur.com/6IkQxQ2) 和代码所写的判断顺序一样,逐个判断。 在看 switch 的,代码如下。 ![switchcode]( https://imgur.com/9PBOKmz) 逆向结果 ![switchreverse]( https://imgur.com/Ox2qH4C) 第一次判断和数值 2 对比,后续采用大于还是小于,进行二分法逐层判断。 所以在写 C/C++的时候,关闭编译器优化的情况下,如果判断分支比较多,采用 switch 效率会更高。 然后在吐个槽……分支真的那么多的时候,是不是应该考虑优化业务逻辑了 |
23
hyd8323268 OP @shendaowu 感谢 晚上回去看看
|
24
hyd8323268 OP @yedanten 兄弟你链接挂了
|
25
labnotok 2019-06-25 16:05:16 +08:00 via Android
由于每个 case 的出现概率不同,
if else 可以利用先验知识优化, 达到实际中的最小复杂度。 |
26
yedanten 2019-06-25 16:08:25 +08:00 via Android
@hyd8323268 额,这个图床要搭梯子……
|
27
psychoo 2019-06-25 16:37:03 +08:00
试了一下 C 语言 1 亿次的 11 条件 if 和 switch,if 比 switch 快一点,不知原因
|
28
wym7223645 2019-06-25 17:10:52 +08:00
java 项目,我们项目要求你使用 if-else 不建议使用 switch,原因就是 业务变化太快,分分钟的加上复杂条件
|
29
jaskle 2019-06-25 19:14:35 +08:00 via Android
其实吧,与语言有关,如果是脚本类还是 if 吧,Java 判断量多的可以用用 switch,c 系的只有数值接近或递增规律明显才会用跳表。总结:哪个方便用哪个,除非你的性能瓶颈不在 io 上,这点性能损耗也就 12306 能用上
|
30
secondwtq 2019-06-25 19:40:37 +08:00 via iPad
|
32
dremy 2019-06-25 19:56:54 +08:00 via iPhone
自以为比编译器聪明系列
|
33
yedanten 2019-06-25 20:54:03 +08:00 via Android
@secondwtq 这不是为了给楼主演示 if 和 switch 在编译后是怎么执行的,才关掉优化嘛,开着优化那反汇编出来的都是二分法判断。
|
34
weixiangzhe 2019-06-25 22:23:42 +08:00
python 就没有 switch 吧,还是看语言吧
|
35
pan519 2019-06-26 01:41:14 +08:00
小白也有类似疑问。。。switch 不是后面只能写 int string 类的嘛?
|
36
csys 2019-06-26 02:19:51 +08:00 via Android
取决于有没有模式匹配
|
37
msg7086 2019-06-26 03:11:09 +08:00
怎么写舒服怎么写。这种细节上的效率优化带来的性能提升太小了。真的遇到性能瓶颈了再做 Profiling 不迟。
|
38
hallwoodzhang 2019-06-26 05:04:49 +08:00 via Android
switch 语句会直接通过条件查表,然后通过 offset 跳到对应指令,if 则没这么快
|
39
zwh2698 2019-06-26 07:12:30 +08:00 via Android 2
科普编译器跳转表,很多 switch 语句编译器在后期都把它转成跳转表,而一般的 if 语句就是汇编的大于等于小于跳转,两个执行的代码多少不同。关键来了:现代编译器对 if 语句一定多个一起的也会做成跳转表,比较少的,就在 peephole 优化阶段删掉更多的无用语句,也不会差很多。
|
40
Mohanson 2019-06-26 09:32:05 +08:00 via Android
语义不同
|
41
ysn2233 2019-06-26 11:26:28 +08:00
现在来说,不带模式匹配的语言感觉没什么区别了都
|
42
hyd8323268 OP @zwh2698 感谢
|