小范围紧凑的判断使用switch语句替代if-else
【说明】 使用Switch/case语句,减少不必要的if语句的多次条件判断。
【原理】 由于switch...case会生成一个跳转表来指示实际的case分支的地址,跳转表的索引号等于switch变量的值,因此switch...case不用像if...else if那样遍历条件分支直到命中条件,从而提升执行效率。
【注意事项】 实际软件编码的过程中,更关键的问题是如何对于逻辑判断和跳转表进行选择:对于已经明确应使用跳表的场景,又因为判决条件的逻辑导致无法采用switch...case的方式实现,则需要通过代码实现跳转表。
【案例】
优化前:
int Func(int choice)
{
int ret = GetA();
if(choice == 1) {
ret = ret + GetB();
}
if (choice == 2) {
ret = ret + GetC();
}
if (choice == 3) {
ret = ret + GetD();
}
if (choice == 4) {
ret = ret + GetE();
}
if (choice == 5) {
ret = ret + GetF();
}
if (choice == 6) {
ret = ret + GetG();
} else {
ret = GetH();
}
return ret;
}
对应的汇编指令如下,当choice的取值大于等于6时,会依次与1、2、3、4、5、6比较:
Func(int):
push {r4, r5, r6, lr}
mov r4, r0
bl GetA()
cmp r4, #1
beq .L13
cmp r4, #2
beq .L14
cmp r4, #3
beq .L15
cmp r4, #4
bne .L7
bl GetE()
.L6:
pop {r4, r5, r6, lr}
b GetH()
.L15:
bl GetD()
pop {r4, r5, r6, lr}
b GetH()
.L14:
bl GetC()
pop {r4, r5, r6, lr}
b GetH()
.L13:
bl GetB()
pop {r4, r5, r6, lr}
b GetH()
.L7:
cmp r4, #5
bne .L3
bl GetF()
pop {r4, r5, r6, lr}
b GetH()
.L3:
cmp r4, #6
bne .L6
mov r5, r0
bl GetG()
add r0, r5, r0
pop {r4, r5, r6, pc}
优化后:
int Func(int choice)
{
int ret = GetA();
switch(choice){
case 1:
ret = ret + GetB();
break;
case 2:
ret = ret + GetC();
break;
case 3:
ret = ret + GetD();
break;
case 4:
ret = ret + GetE();
break;
case 5:
ret = ret + GetF();
break;
case 6:
ret = ret + GetG();
break;
default:
ret = GetH();
}
return ret;
}
对应的汇编代码:
Func(int):
push {r4, r5, r6, lr}
mov r4, r0
bl GetA()
mov r5, r0
sub r0, r4, #1
cmp r0, #5
ldrls pc, [pc, r0, asl #2]
b .L2
.word .L3
.word .L5
.word .L6
.word .L7
.word .L8
.word .L9
.L9:
bl GetG()
add r0, r5, r0
pop {r4, r5, r6, pc}
.L3:
bl GetB()
add r0, r5, r0
pop {r4, r5, r6, pc}
.L5:
bl GetC()
add r0, r5, r0
pop {r4, r5, r6, pc}
.L6:
bl GetD()
add r0, r5, r0
pop {r4, r5, r6, pc}
.L7:
bl GetE()
add r0, r5, r0
pop {r4, r5, r6, pc}
.L8:
bl GetF()
add r0, r5, r0
pop {r4, r5, r6, pc}
.L2:
pop {r4, r5, r6, lr}
b GetH()
需要注意的是,编译器也会针对条件判断逻辑进行优化,针对部分场景下的if语句,可能在编译阶段被优化成跳转表的实现(即switch的方式)。
父主题: 控制语句