Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Performance difference of "if if" vs "if else if"

Tags:

c++

c

I was just thinking is there any performance difference between the 2 statements in C/C++:

Case 1:

if (p==0)    do_this(); else if (p==1)    do_that(); else if (p==2)    do_these(): 

Case 2:

if(p==0)     do_this(); if(p==1)     do_that(); if(p==2)     do_these(); 
like image 840
Syntax_Error Avatar asked Nov 01 '11 17:11

Syntax_Error


People also ask

Is if-else faster than if if?

In general, "else if" style can be faster because in the series of ifs, every condition is checked one after the other; in an "else if" chain, once one condition is matched, the rest are bypassed.

What is the difference between if if and if-else if?

Use if to specify a block of code to be executed, if a specified condition is true. Use else to specify a block of code to be executed, if the same condition is false. Use else if to specify a new condition to test, if the first condition is false.

Does if-else affect performance?

In general it will not affect the performance but can cause unexpected behaviour. In terms of Clean Code unneserry if and if-else statements have to be removed for clarity, maintainability, better testing. One case where the performance will be reduced because of unnecessary if statements is in loops.

Is else if more efficient?

A switch statement is usually more efficient than a set of nested ifs. Deciding whether to use if-then-else statements or a switch statement is based on readability and the expression that the statement is testing.


2 Answers

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.

like image 58
derobert Avatar answered Oct 09 '22 11:10

derobert


In the former case conditions after the one matched are not evaluated.

like image 31
Michael Krelin - hacker Avatar answered Oct 09 '22 09:10

Michael Krelin - hacker