switch 和 if else的效率区别

一.若是switch(x)中的x能静态确定,两者效率一样。我们看下反汇编代码:
静态源代码
静态反汇编
switch和if/else两者都是push、push、push、call的形式,即传递三个参数,第一个为:"%d,%d",第二个为:a的值,第三个为b的值。所以效率一样。

二.若条件得动态确定,也得分两种情况讨论:
1.当条件不多时,两者效率非常接近,看下图:
动态确定switch
可以看见判断a=1、2、3的过程,每次dec eax(减1),然后jz short xxxx。也就是先比较是否等于3,再比较是否等于2,最后判断是否为1。都是判断后再减1与下个条件比较的。
if/else的实现如下图:
动态确定if/else
看见cmp edi,1和cmp edi,2了吗,也就是先与1比较,再与2比较,都不相等就是3了。cmp比较是做减法,先减1,再减2。
所以,两者几乎没区别。要说区别,switch多了一次判断,if/else有个减2。

2.当条件很多时,switch比if/else效率高。因为switch实现使用跳转表实现的,条件多的甚至用2、3级跳转表实现。
见下图:
点击查看原始尺寸
点击查看原始尺寸
看见“jmp ds:off_40108C[eax4] ; switch jump”这句了吗,eax是switch(x)中的x。“dd offset loc_xxxxxx”这些就是跳转表,存放的是一个一个case:地址。所以是通过jmp ds:off_40108C[eax4]直接跳转过去的(基址+变址寻址)。
而if/else的实现方式见下图:
动态确定if/else1
动态确定if/else2
可以看见if/else仍然采用cmp xxx,1 jnz xxx、cmp xxx,2 jnz xxx、cmp xxx,3 jnz xxx...的方式实现的。
所以当条件很多时,switch比if/else效率高。



if else是一条比较指令,需要遍历条件分支直到命中条件

而swtich是一张地址表,而只需访问对应索引号的表项就能定位分支,所以switch有点以空间换时间的意思。

用优点来描述一下就明白了:

  1. switch优点

当分支较多时,用switch的效率是很高的。因为switch是随机访问的,就是确定了选择值之后直接跳转到那个特定的分支,但是if else是遍历所以得可能值,知道找到符合条件的分支。如此看来,switch的效率确实比if else要高的多。

但是case常量分布范围很大但实际有效值又比较少的情况,switch的空间利用率将变得很低。

  1. if优点

switch只能处理常量的情况,对非常量的情况是无能为力的。像a > 1 && a < 100,这种表达式是无法使用switch的,只能用if else。所以if else能应用于更多的场合。


对于switch(x)和if(x),两者孰快孰慢取决于语句x在编译和运行期的情况。

  1. 如果x在编译期就能计算出来,那么运行的时候速度上就看不到区别,都是一个跳转语句,编译器进行了优化处理。
  2. 如果x需要根据运行时的情况计算然后进行处理,那么两者有可能有差别,但是分情况
  
  
  1. 2.1 如果x的结果是很简单的一个数字,字符,或者其他内置数据类型数据,那么两者的运行速度一样,都是进行判断然后跳转。
  2. 2.2 如果x需要进行复杂的计算(这真是if的长处,switch是没法做到的),那么if语句做计算的时间就是比switch多出的时间。

因此,从总体情况来看,if花费的时间 >= switch花费的时间。但是从语法角度来说,if语句的功能要比switch要强,switch算是一种特殊情况下的经过优化的if


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值