if else和switch的效率

摘要:
我昨天找到了一本叫做CSAPP的书,终于找到了切换问题的答案。与if-else结构相比,开关的效率肯定要高得多,但开关使用查找表的方式决定了case的条件必须是连续常数。可以看出,如果else被简单地逐一比较,效率相对较低。可以看出,开关的效率通常高于if-else。开关的效率更高。从汇编代码中可以看出,switch只计算一次值,如果为每个条件计算Else,那么它就是test,jmp。开关的效率与支路的数量无关。当只有分支数较少时,if的效率高于switch,当然,switch的分支数更多

switch和if-else相比,由于使用了Binary Tree算法,绝大部分情况下switch会快一点,除非是if-else的第一个条件就为true. 
说实话  我也没有深入研究过这个问题的根源 
只是在实际开发中  没有人会去用很多很多else if的 
都是用 switch case 的  后者比较清晰  给人感觉就是一个脑子很清楚的人写出来的东西 
至于效率的本质  就让大企鹅去操心吧 

编译器编译switch与编译if...else...不同。不管有多少case,都直接跳转,不需逐个比较查询。 

昨天发现了一本叫做CSAPP的书,终于找到了关于switch问题的解答。 
这是一段C代码: 
/* $begin switch-c */ 
int switch_eg(int x) 

    int result = x; 

    switch (x) { 

    case 100: 
    result *= 13; 
    break; 

    case 102: 
    result += 10; 
    /* Fall through */ 

    case 103: 
    result += 11; 
    break; 

    case 104: 
    case 106: 
    result *= result; 
    break; 

    default: 
    result = 0;       
    } 

    return result; 

/* $end switch-c */ 

用GCC汇编出来的代码如下: 
    .file    "switch.c" 
    .version    "01.01" 
gcc2_compiled.: 
.text 
    .align 4 
.globl switch_eg 
    .type     switch_eg,@function 
switch_eg: 
    pushl %ebp 
    movl %esp,%ebp 
    movl 8(%ebp),%edx 
    leal -100(%edx),%eax 
    cmpl ,%eax 
    ja .L9 
    jmp *.L10(,%eax,4) 
    .p2align 4,,7 
.section    .rodata 
    .align 4 
    .align 4 
.L10: 
    .long .L4 
    .long .L9 
    .long .L5 
    .long .L6 
    .long .L8 
    .long .L9 
    .long .L8 
.text 
    .p2align 4,,7 
.L4: 
    leal (%edx,%edx,2),%eax 
    leal (%edx,%eax,4),%edx 
    jmp .L3 
    .p2align 4,,7 
.L5: 
    addl ,%edx 
.L6: 
    addl ,%edx 
    jmp .L3 
    .p2align 4,,7 
.L8: 
    imull %edx,%edx 
    jmp .L3 
    .p2align 4,,7 
.L9: 
    xorl %edx,%edx 
.L3: 
    movl %edx,%eax 
    movl %ebp,%esp 
    popl %ebp 
    ret 
.Lfe1: 
    .size     switch_eg,.Lfe1-switch_eg 
    .ident    "GCC: (GNU) 2.95.3 20010315 (release)" 

在上面的汇编代码中我们可以很清楚的看到switch部分被分配了一个连续的查找表,switch case中不连续的部分也被添加上了相应的条目,switch表的大小不是根据case语句的多少,而是case的最大值的最小值之间的间距。在选择相应 的分支时,会先有一个cmp子句,如果大于查找表的最大值,则跳转到default子句。而其他所有的case语句的耗时都回事O(1)。 

相比于if-else结构,switch的效率绝对是要高很多的,但是switch使用查找表的方式决定了case的条件必须是一个连续的常量。而if-else则可以灵活的多。 


可以看到if-else只是单纯地一个接一个比较,效率比较低 

可以看出,switch的效率一般比if-else高 


switch   效率高,     从汇编代码可以看出来   
switch   只计算一次值   然后都是test   ,   jmp,     
if...else   是每个条件都要计算一遍的.  

switch的效率与分支数无关   
 当只有分支比较少的时候,if效率比switch高(因为switch有跳转表)   
 分支比较多,那当然是switch

免责声明:文章转载自《if else和switch的效率》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇ByteBuf Netty的数据容器ADOEF连接字符串问题下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

java关于for循环的效率优化

我们知道在实现一个功能的时候是可以使用不同的代码来实现的,那么相应的不同实现方法的性能肯定也是有差别的,所以我们在写一些对性能很敏感的模块的时候,对代码进行优化是很必要的,所以我们说一下for循环(while循环同理)的性能优化。 循环作为三大结构之一,我们在编写代码的时候使用频率非常的高;循环结构的重要性也是不言而喻的,他让我们操作数组、集合和其他一些...

【转】C#字符串连接的效率问题

C#字符串连接常用的四种方式:StringBuilder、+、string.Format、List<string>。 1.+的方式 string sql = "update tableName set int1=" + int1.ToString() + ",int2=" + int2.ToString() + ",int3=" + int3....

Notepad++提升工作效率小技巧

前言简单的提升工具效率需求可以借助Notepad编辑器实现。以前也用Python/Shell开发过本文中提到的需求,现在发现其实没有必要。本文介绍一些工作中常见的可以通过"Notepad+正则表达式"实现的案例供参考。另外,强调一下,学好正则表达式很有用。 提升效率需求需求1:将指定一行字符串"123456789"拆分成多个字符,每个字符在一行中显示。常用...

SQL -去重Group by 和Distinct的效率

经实际测试,同等条件下,5千万条数据,Distinct比Group by效率高,但是,这是有条件的,这五千万条数据中不重复的仅仅有三十多万条,这意味着,五千万条中基本都是重复数据。 为了验证,重复数据是否对其有影响,本人针对80万条数据进行测试: 下面是对CustomerId去重,CustomerId的重复项及其多,80万条中仅仅50条不重复的。可以看到,...

键盘快速启动工具Launchy的简单使用技巧

打开电脑面对林林总总的图标,找到对应的程序,快速启动显得尤为重要.这样有利于提高我们的效率. 好了,直接上图: 就是这款小巧的工具,界面如上. 接下来介绍这款工具的使用技巧. 1.安装成功后:打开工具之后,我们可以编辑热键,按照我们个人的操作习惯,设置自己熟悉的热键.工具默认热键是ALT+SPACE(空格键)                以后每次打开工具...

(转)sql union和union all的用法及效率

1 熟悉union的相关操作 UNION指令的目的是将两个SQL语句的结果合并起来。从这个角度来看, 我们会产生这样的感觉,UNION跟JOIN似乎有些许类似,因为这两个指令都可以由多个表格中撷取资料。 UNION的一个限制是两个SQL语句所产生的栏位需要是同样的资料种类。 另外,当我们用 UNION这个指令时,我们只会看到不同的资料值 (类似 SELEC...