Switch Vs if-else

Which one consumes more processing time?

Switch function or if-else?

just wondering.
Depends on optimisation.
Usually difference is neglible.
Oh oh oh.. :) Thank you sir. You have helped me again. <3
To be precise, having a switch instead of many if/then/else allows the compiler to easily optimize your program (usually via a jumplist), whereas if/then/else optimization will result in a harder optimization.
The more your compiler knows what you want to do, the better it can optimize it.
It makes no difference whatsoever to the compiler.

Choose the construct that is more readable and maintainable (more programmer efficient).

Leave low level optimization to the compiler; it does that a lot better than most programmers.
Focus on optimisations that the compiler can't do for us - choice of data structures, algorithms, and other high level constructs.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
int foo( int a )
{
    if( a == 0 ) return 5 ;
    else if( a == 1 ) return 22 ;
    else if( a == 2 ) return 0 ;
    else if( a == 3 ) return 7 ;
    else if( a == 4 ) return 1 ;
    else if( a == 5 ) return 100 ;
    else return 50 ;
    
    /*
        _Z3fooi:                                # @_Z3fooi
        	cmpl	$5, %edi
        	ja	.LBB0_2
        	movslq	%edi, %rax
        	movl	.Lswitch.table1(,%rax,4), %eax
        	retq
        .LBB0_2:
        	movl	$50, %eax
        	retq    
    */
}

int bar( int a )
{
    switch(a)
    {
        case 0: return 5 ;
        case 1:  return 22 ;
        case 2:  return 0 ;
        case 3:  return 7 ;
        case 4:  return 1 ;
        case 5:  return 100 ;
        default: return 50 ; 
    }
    /*
        _Z3bari:                                # @_Z3bari
        	cmpl	$5, %edi
        	ja	.LBB1_2
        	movslq	%edi, %rax
        	movl	.Lswitch.table1(,%rax,4), %eax
        	retq
        .LBB1_2:
        	movl	$50, %eax
        	retq
    */
}

/*
    .Lswitch.table1:
    	.long	5                       # 0x5
    	.long	22                      # 0x16
    	.long	0                       # 0x0
    	.long	7                       # 0x7
    	.long	1                       # 0x1
    	.long	100                     # 0x64
*/

http://coliru.stacked-crooked.com/a/210b401221d089b8
Binary search tree may be build for switch. So Visual Studio optimize switch to O(ln N), while if ... else is only O(N). Maybe gcc do the same.

For example, you compare in to 1,3,5,7,10,20,30.

Sorry for bad pseudographic. If it's not clear, I can write pseudocode.
1
2
3
4
5
6
7
                 /->(<)->(x?1)(=)--> #1
    /->(<)-->(x?3)-->(=) - - - - - > #3
   /             \->(>)->(x?5)(=)--> #5
(x?7)->(=)- - - - - - - - - - - - -> #7
   \             /->(<)->(x?10)(=)-> #10
    \->(>)->(x?20)->(=)- - - - - - > #20
                 \->(>)->(x?30)(=)-> #30 

Every comparsion generate 1 cmp (x?7) and 1 or 2 conditional jumps (=, >).
So maximum 3 comparsions.

For if..else
1
2
3
4
(x?1)->(x?3)->(x?5)->(x?7)->(x?10)->(x?20)->(x?30)
 (=)    (=)    (=)    (=)    (=)     (=)     (=)
  V      V      V      V      V       V       V
 #1     #3     #5     #7     #10     #20     #30 

Maximum up to 7 comparsions.
Binary search tree may be build for switch
There is no reason why it cannot be built for if/else too.

And jump tables might be built for both (demonstrated by JLBorges). And they are O(1).
Reason, why binary tree can't be build for if/else it that it can break logic.
1
2
3
if (x == func1()) {...}
else if (x == func2()) {...}
else if (x == func3()) {...}

Here compiler have no rights to call func2() before func1().

Jump tables can be build only for very small values. What about comparing x with 1000000000?

But in very very specifit situations you're right, if/else can be downgraded to binary tree and jump tables can be build.
Reason, why binary tree can't be build for if/else it that it can break logic.
We are talking about perfomance (and choice) of switch/if-else in some case. In your case you simply cannot replace it with switch as-is.

What about comparing x with 1000000000?
Try it. Clang builds same code for both switch and if-else: something that looks like binary tree. (Although there is possibility to build jump table for it, compilers are either not smart enough or decide that testing/conversion overhead is not worth it)
Thanks for the answer guys. :)

Does if-else statement still check for the next "else-if" conditionS after checking for the "if" condition?

This bothers me in case of many logical checks and comparisons.. :)
Last edited on
Does if-else statement still check for the next "else-if" conditionS after checking for the "if" condition?
Only if the if condition is not satisfied. If it is then it should ignore/skip past the else statement.
Thanks for the reply sir :)
What i mean is that,
after the if condition is met,
does that mean that it will still check vs. else-if conditions?
It does not check those conditions; they are only checked in the case that the preceding conditions are not satisfied.
> after the if condition is met, does that mean that it will still check vs. else-if conditions?

The observable behaviour of the program would be as-if it first checked the if condition, and if that was met, the else-if conditions were not checked.

The compiler is allowed to rewrite the code as long as the observable behaviour of the rewritten code is indistinguishable from the observable behaviour of the original code.
http://en.cppreference.com/w/cpp/language/as_if

If we write:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int foo( int a )
{
    int b = 0 ; 
    
    if( a < 7 ) b += 5 ;
    else if( a > 9 ) b += 6 ;
    else if( a == 7 ) b += 5 ;
    else if( a > 10 ) b += 6 ;
    else if( a == 8 ) b += 5 ;
    else if( a == 11 ) b += 6 ;
    else if( a == 9 ) b += 5 ;
    else b += 6 ;
    
    if( a < 7 ) b += 15 ;
    else if( a > 9 ) b += 26 ;
    else if( a == 7 ) b += 15 ;
    else if( a > 10 ) b += 26 ;
    else if( a == 8 ) b += 15 ;
    else if( a == 11 ) b += 26 ;
    else if( a == 9 ) b += 15 ;
    else b += 26 ;

    return b ;
}


a compiler is allowed to generate code as if foo() was: int foo( int a ) { return a > 9 ? 32 : 20 ; }

_Z3fooi:
.LFB0:
	.cfi_startproc
	cmpl	$9, %edi
	movl	$20, %edx
	movl	$32, %eax
	cmovle	%edx, %eax
	ret
	.cfi_endproc

http://coliru.stacked-crooked.com/a/3a7a541c34f40aa6

Repeat: Leave low level optimization to the compiler.
Oh i see, that's the reason maybe why there are no "break" statements in the if-else conditions. :)

Thank you for your effort in answering my "simple" question. :)
Leave low level optimization to the compiler.

I agree.

In addition, choose the language construct that most closely reflects the logic of your algorithm. If the logic is "do X, Y, or Z depending on the value of k" then a switch statement would make sense. This helps another programming understand your code.
Consider using arrays if possible (more often than you might think) and speed is an issue. Extra code for boundary checks is negligible for large case statements.

1
2
3
4
5
6
int lut[] = {5,22,0,7,1,100};

int foo( int a )
{
  return lut[a];
}
Topic archived. No new replies allowed.