I had a debate lately about micro optimizations in C++ and what structures are faster: IF or SWITCH. Until now, I honestly didn’t encounter a scenario where the speed difference between these two structures could be objectively measured but hey, I’m a curious man and decided to look under the hood to see exactly how are they compiled by GCC.
Let’s see the IF statement:
int sampleIF(char c) {
if (c == '1')
return 1;
else if (c == '2')
return 2;
else if (c == '3')
return 3;
else if (c == '4')
return 4;
else if (c == '5')
return 5;
return 6;
}
The equivalent assembly code is:
sampleIF(char):
cmp dil, 49
je .L12
mov eax, 2
cmp dil, 50
je .L11
mov al, 3
cmp dil, 51
je .L11
mov al, 4
cmp dil, 52
je .L11
cmp dil, 53
setne al
movzx eax, al
add eax, 5
ret
.L12:
mov eax, 1
.L11:
rep ret
As you can see, there is nothing special here. It is a simple translation of the IF statements. For each IF there is a JE condition, really straight forward. Now lets see the equivalent switch code:
int sampleSwitch(char c) {
switch (c) {
case '1' : return 1;
case '2' : return 2;
case '3' : return 3;
case '4' : return 4;
case '5' : return 5;
}
return 6;
}
And the ASM:
sampleSwitch(char):
sub edi, 49
cmp dil, 4
ja .L2
movzx edi, dil
jmp [QWORD PTR .L4[0+rdi*8]]
.L4:
.quad .L9
.quad .L5
.quad .L6
.quad .L7
.quad .L8
mov eax, 2
ret
mov eax, 3
ret
mov eax, 4
ret
mov eax, 5
ret
.L2:
mov eax, 6
ret
mov eax, 1
ret
Jesus Christ, that code looks ugly. It is a jump table and it tries to minimize the effect of the worst case scenario. In case of an IF, to execute the last branch, all the above conditions must be evaluated. With switch you can jump to that last branch “almost directly”. That said, until now, I never had the privilege to work on a code where the speed difference between these two would matter.