Performance difference of "if if" vs "if else if"
Solution 1:
Assuming simple types (in this case, I used int
) and no funny business (didn't redefine operator= for int), at least with GCC 4.6 on AMD64, there is no difference. The generated code is identical:
0000000000000000 <case_1>: 0000000000000040 <case_2>:
0: 85 ff test %edi,%edi 40: 85 ff test %edi,%edi
2: 74 14 je 18 <case_1+0x18> 42: 74 14 je 58 <case_2+0x18>
4: 83 ff 01 cmp $0x1,%edi 44: 83 ff 01 cmp $0x1,%edi
7: 74 27 je 30 <case_1+0x30> 47: 74 27 je 70 <case_2+0x30>
9: 83 ff 02 cmp $0x2,%edi 49: 83 ff 02 cmp $0x2,%edi
c: 74 12 je 20 <case_1+0x20> 4c: 74 12 je 60 <case_2+0x20>
e: 66 90 xchg %ax,%ax 4e: 66 90 xchg %ax,%ax
10: f3 c3 repz retq 50: f3 c3 repz retq
12: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1) 52: 66 0f 1f 44 00 00 nopw 0x0(%rax,%rax,1)
18: 31 c0 xor %eax,%eax 58: 31 c0 xor %eax,%eax
1a: e9 00 00 00 00 jmpq 1f <case_1+0x1f> 5a: e9 00 00 00 00 jmpq 5f <case_2+0x1f>
1f: 90 nop 5f: 90 nop
20: 31 c0 xor %eax,%eax 60: 31 c0 xor %eax,%eax
22: e9 00 00 00 00 jmpq 27 <case_1+0x27> 62: e9 00 00 00 00 jmpq 67 <case_2+0x27>
27: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1) 67: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1)
2e: 00 00 6e: 00 00
30: 31 c0 xor %eax,%eax 70: 31 c0 xor %eax,%eax
32: e9 00 00 00 00 jmpq 37 <case_1+0x37> 72: e9 00 00 00 00 jmpq 77 <case_2+0x37>
37: 66 0f 1f 84 00 00 00 nopw 0x0(%rax,%rax,1)
3e: 00 00
The extra instruction at the end of case_1 is just for padding (to get the next function aligned).
This isn't really surprising, figuring out that p isn't changed in that function is fairly basic optimization. If p could be changed (e.g., passed-by-reference or pointer to the various do_…
functions, or was a reference or pointer itself, so there could be an alias) then the behavior is different, and of course the generated code would be too.
Solution 2:
In the former case conditions after the one matched are not evaluated.
Solution 3:
if else is faster; if a match was found before the last if then at least the last if statement is skipped, if match was found in first it will skip all other statements.
if if is slower; even if a match was found using the first if statement, it will keep on trying to match in other statement.
Solution 4:
Yes the performance difference is:
The second statement evaluate every IF
Solution 5:
You probably won’t notice any difference in performance for such a limited number of expressions. But theoretically, the if..if..if
requires to check every single expression. If single expressions are mutally exclusive, you can save that evaluation by using if..else if..
instead. That way only when the previous cases fail, the other expression is checked.
Note that when just checking an int for equality, you could also just use the switch
statement. That way you can still maintain some level of readability for a long sequence of checks.
switch ( p )
{
case 0:
do_this();
break;
case 1:
do_that();
break;
case 2:
do_these():
break;
}