写着代码写着代码,想到一个很纠结的问题,就是switch与ifelse的效率问题

是在受不了了,就去网上查了下。转载下http://blog.csdn.net/kehui123/article/details/5298337

switch与if..else 的执行的效率问题
 今天读一前辈的程序,发现其在串口中断里面为了分析协议的报文类型,在中断函数里面使用if..else语句。因为报文类型在现在看来只有两种,以后有可能还会增加,不确定。
 本人以为这样用有些不妥,为什么不用switch语句呢?猜想是不是因为效率方面的考虑呢,毕竟我们应该尽量是中断的处理代码更加简洁,时间效率更高才好。
 所以本人就查找相关资料,资料显示switch语句反而比ifelse的执行效率要高。
 下面来详细描述switch与ifelse的区别。
 switch...case与if...else的根本区别在于,switch...case会生成一个跳转表来指示实际的case分支的地址,而这个跳转表的索引号与switch变量的值是相等的。从而,switch...case不用像if...else那样遍历条件分支直到命中条件,而只需访问对应索引号的表项从而到达定位分支的目的。
具体地说,switch...case会生成一份大小(表项数)为最大case常量+1的跳表,程序首先判断switch变量是否大于最大case 常量,若大于,则跳到default分支处理;否则取得索引号为switch变量大小的跳表项的地址(即跳表的起始地址+表项大小*索引号),程序接着跳到此地址执行,到此完成了分支的跳转。
//

 1 int main()
 2 {
 3  unsigned int i,j;
 4  i=3;
 5  switch (i)
 6  {
 7   case 0:
 8   j=0;
 9   break;
10   case 1:
11   j=1;
12   break;
13   case 2:
14   j=2;
15   break;
16   case 3:
17   j=3;
18   break;
19   case 4:
20   j=4;
21   break;
22   default:
23   j=10;
24   break;
25  }
26
27
28 }

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

.file "shiyan.c".text
.globl main.type main, @function
main:leal 4(%esp), %ecxandl $-16, %esppushl -4(%ecx)pushl %ebpmovl %esp, %ebppushl %ecxsubl $20, %espmovl $3, -8(%ebp)cmpl $4, -8(%ebp)ja .L2movl -8(%ebp), %eaxsall $2, %eaxmovl .L8(%eax), %eaxjmp *%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, %esppopl %ecxpopl %ebpleal -4(%ecx), %espret.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比较灵活。

由此看来,上面前辈的中断处理程序中用switch是比较合适的,即节省了时间,而且对于以后程序的扩展也是很方便。因为报文类型这个值基本上都是用整形常量来表示的。

转载于:https://www.cnblogs.com/muyue/archive/2012/11/22/2782972.html

(转)switch与ifelse的效率问题 .相关推荐

  1. switch if c语言效率,switch与ifelse的效率问题

    switch...case与if...else的根本区别在于,switch...case会生成一个跳转表来指示实际的case分支的地址,而这个跳转表的索引号与switch变量的值是相等的.从而,swi ...

  2. c语言if-else的效率比较

    闲着没事测试下if-else的执行效率 测试环境:Mac pro i7 2.3Ghz ...编译器gcc 4.9,代码没有进行优化-O0: 测试代码:c代码1: int main(){int n=10 ...

  3. switch-case和if-else的效率比较·必看

    绝大多数的程序员喜欢使用if判断,但是真的效率高吗?还是其它的,可能只会用if呢!我们今天就具体测一测,用事实说话,测试量100W: 理论上,switch是利用空间换时间.为了避免实验干扰,先行执行了 ...

  4. c语言switch中用ifelse,初学者求问:用if单分支选择语句替换switch语句?if.else呢...

    菜鸟求问:用if单分支选择语句替换switch语句?if...else呢? 主要是关于default情况的处理,代码如下: /* Fig. 4.7: fig04_07.c Counting lette ...

  5. 学习Winform了解到switch和if-else的妙处

    创建一个窗体应用,在窗口点击鼠标可以循环出现图片. 点击窗口F6出现和窗口相关代码. 可以将窗口点击鼠标的方法看为一个循环体. swtich(i){case 0:BackColor = Color.Y ...

  6. switch写打折促销活动C语言,求C语言大神编一个程序(分别用switch和if-else结构)某商店推出打折活动,要求购物达到或超过2000元的...

    满意答案 xQiIbnhdrv 2013.01.14 采纳率:50%    等级:10 已帮助:317人 展开全部 123456789101112131415161718192021222324252 ...

  7. php switch 判断多个,php switch语句多个值匹配同一代码块的实现

    php switch语句多个值匹配同一代码块的实现 先说说switch()语句的格式 switch(表达式){ case 匹配1: 当匹配1和表达式匹配成功执行的代码; break; case 匹配2 ...

  8. php mysql 复制数据库表结构图_MySQL_Mysql复制表结构、表数据的方法,本文给大家分享了好几种复制 - phpStudy...

    Mysql复制表结构.表数据的方法 本文给大家分享了好几种复制表结构.表数据的示例介绍,具体详情请看下文吧. 1.复制表结构及数据到新表 CREATE TABLE 新表SELECT * FROM 旧表 ...

  9. 基于C语言控制台程序的简易MP3音乐播放器

    这是我们小学期的第一个大作业,因感受颇深,特此写下这篇博客留作纪念. 内容:设计一个带有播放控制和音量调节功能的控制台音乐播放器,其中播放控制的子菜单能实现播放暂停切换.停止当前曲.播放上一曲和下一曲 ...

  10. if else和switch的效率

    switch和if-else相比,由于使用了Binary Tree算法,绝大部分情况下switch会快一点,除非是if-else的第一个条件就为true.  说实话  我也没有深入研究过这个问题的根源 ...

最新文章

  1. word2vec python实现_教程 | 在Python和TensorFlow上构建Word2Vec词嵌入模型
  2. 最大熵学习笔记(六)优缺点分析
  3. 计算机指令取决,不同的计算机,其指令不同,这主要取决于什么?
  4. 微信接口开发-初级体验
  5. php三级实例,三级联动实例
  6. for循环与each遍历的跳出循环方式
  7. 在stackoverflow上使用markdown
  8. 以后的blog将转移到微信公众号,请扫码关注谢谢!
  9. linux 文件名加粗,linux – 具有粗体字体的显示目录 – 如何启用?用.bash_profile?...
  10. 目前看的GNN论文的一些总结
  11. 有哪些激光雷达SLAM算法?
  12. ModuleNotFoundError: No module named ‘MySQLdb‘
  13. 阿里矢量库的图标使用教程(在线,下载)
  14. 电力电子技术笔记(1)
  15. 基于Linux操作系统的在线英英词典C语言代码
  16. 微型计算机任务名称,任务五微型计算机的硬件组成.ppt
  17. 代数拓扑1|单纯同调
  18. mysql用户域账户登录_使用本地系统帐户和域用户帐户两者区别(microsoft SQLServer2000...
  19. java 计算年龄_java实现简单年龄计算器
  20. python读Excel数据成numpy数组

热门文章

  1. mybatis源码学习方式
  2. Mybatis trim 标签的 2 个妙用!
  3. 关于Spring,所有的都在这了,具有收藏价值
  4. 【漫画】996对程序员的伤害,一看你就懂
  5. 动辄几个亿的东半球最强饭局:大佬们都吃了啥?
  6. 中国最惨创业者的惨痛教训!
  7. 有关于Java中JFrame方法的基本操作
  8. __proto__和prototype 小记
  9. 2.泡妞与设计模式(三) 外观模式
  10. bootstrap table 服务器端分页--ashx+ajax