博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
switch与ifelse的效率问题
阅读量:6250 次
发布时间:2019-06-22

本文共 1666 字,大约阅读时间需要 5 分钟。

  switch...case与if...else的根本区别在于,switch...case会生成一个跳转表来指示实际的case分支的地址,而这个跳转表的索引号与switch变量的值是相等的。从而,switch...case不用像if...else那样遍历条件分支直到命中条件,而只需访问对应索引号的表项从而到达定位分支的目的。

  具体地说,switch...case会生成一份大小(表项数)为最大case常量+1的跳表,程序首先判断switch变量是否大于最大case 常量,若大于,则跳到default分支处理;否则取得索引号为switch变量大小的跳表项的地址(即跳表的起始地址+表项大小*索引号),程序接着跳到此地址执行,到此完成了分支的跳转。

 

int main()

{
 unsigned int i,j;
 i=3;
 switch (i)
 {
  case 0:
  j=0;
  break;
  case 1:
  j=1;
  break;
  case 2:
  j=2;
  break;
  case 3:
  j=3;
  break;
  case 4:
  j=4;
  break;
  default:
  j=10;
  break;
 }
}

 

用gcc编译器,生成汇编代码(不开编译器优化)

 .file "shiyan.c"
 .text
.globl main
 .type main, @function
main:
 leal 4(%esp), %ecx
 andl $-16, %esp
 pushl -4(%ecx)
 pushl %ebp
 movl %esp, %ebp
 pushl %ecx
 subl $20, %esp
 movl $3, -8(%ebp)
 cmpl $4, -8(%ebp)
 ja .L2
 movl -8(%ebp), %eax
 sall $2, %eax
 movl .L8(%eax), %eax
 jmp *%eax
 .section .rodata
 .align 4
 .align 4
.L8:
 .long .L3
 .long .L4
 .long .L5
 .long .L6
 .long .L7
 .text
.L3:
 movl $0, -12(%ebp)
 jmp .L11
.L4:
 movl $1, -12(%ebp)
 jmp .L11
.L5:
 movl $2, -12(%ebp)
 jmp .L11
.L6:
 movl $3, -12(%ebp)
 jmp .L11
.L7:
 movl $4, -12(%ebp)
 jmp .L11
.L2:
 movl $10, -12(%ebp)
.L11:
 addl $20, %esp
 popl %ecx
 popl %ebp
 leal -4(%ecx), %esp
 ret
 .size main, .-main
 .ident "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3"
 .section .note.GNU-stack,"",@progbits

由此看来,switch有点以空间换时间的意思,而事实上也的确如此。
1.当分支较多时,当时用switch的效率是很高的。因为switch是随机访问的,就是确定了选择值之后直接跳转到那个特定的分支,但是if。。else是遍历所以得可能值,知道找到符合条件的分支。如此看来,switch的效率确实比ifelse要高的多。
2.由上面的汇编代码可知道,switch...case占用较多的代码空间,因为它要生成跳表,特别是当case常量分布范围很大但实际有效值又比较少的情况,switch...case的空间利用率将变得很低。
3.switch...case只能处理case为常量的情况,对非常量的情况是无能为力的。例如 if (a > 1 && a < 100),是无法使用switch...case来处理的。所以,switch只能是在常量选择分支时比ifelse效率高,但是ifelse能应用于更多的场合,ifelse比较灵活。

转载地址:http://xhusa.baihongyu.com/

你可能感兴趣的文章
[BZOJ 2140]稳定婚姻(强连通分量)
查看>>
人工智能工程师学习路线
查看>>
Nginx入门(2)反向代理和负载均衡
查看>>
MySQL库表状态查询
查看>>
【鲁班学院】干货分享!《面试必备之Mysql索引底层原理分析》
查看>>
第十一周项目0-是春哥啊
查看>>
poi做一个简单的EXCAL
查看>>
几种查询emacs帮助的办法
查看>>
Python_基础_(模块,time,random,os,sys,json,shelve,xml,序列化反序列化)
查看>>
异常:Project configuration is not up-to-date with pom.xml解决方案
查看>>
HDU2647 拓扑排序
查看>>
ThinkPHP/---微信支付PC流程
查看>>
JavaScript 05
查看>>
python 多线程编程之threading模块(Thread类)创建线程的三种方法
查看>>
实验三
查看>>
水仙花数
查看>>
P3308 [SDOI2014]LIS(最小割+退流)
查看>>
C语言作业--数据类型
查看>>
压位高精
查看>>
jsp 中对jar 包的引用
查看>>