本帖最后由 shenqi 于 2013-4-25 07:12 编辑
switch和if-else相比,由于使用了Binary Tree算法,绝大部分情况下switch会快一点,除非是if-else的第一个条件就为true.
一本叫做CSAPP的书,关于switch问题的解答。
这是一段C代码:
有JAVA基础,这段代码看起来应该不难。- 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部分被分配了一个连续的查找表,switch case中不连续的部分
也被添加上了相应的条目,switch表的大小不是根据case语句的多少,而是case的最大值的最小值之间的间距。
在选择相应 的分支时,会先有一个cmp子句,如果大于查找表的最大值,则跳转到default子句。
相比于if-else结构,switch的效率绝对是要高很多的,但是switch使用查找表的方式决定了case的条件必须是一个
连续的常量。而if-else则可以灵活的多。
但是尽管如此,我们强大的sun公司把switch和if的性能优化得不相上下。
有同学做了简单的测试:
对有多个条件式的switch和if做比较,发现两者的效率几乎相同,if的效率甚至高于switch;<测试环境sun jdk6.1.13>
40个条件式的测试,测试1000 0000次,if耗时219ms, switch耗时234ms,平均都在4-5k/s;
30个条件式的测试,测试1000 0000次,if耗时188 switch耗时172平均都在5-6kw/s,
20个条件式,测试1000 0000次,if耗时109mswitch耗时125ms,平均在8-9kw/s 总结: 1 经过jdk的改进,目前switch和if的性能上差别微乎其微 2 条件式的多少对于一般应用的整体性能来说,影响也非常小。 3 影响效率的最大因子是条件式的数量,而非if或switch
|