Thread: Switch-Case vs If-Else loops

  1. #1
    Registered User
    Join Date
    Dec 2012
    Posts
    37

    Switch-Case vs If-Else loops

    Hi everyone,

    does anyone know the size between switch-case and if-else loops? which one is bigger in size? or in other words, which of these two occupy more space (in memory) when using?

  2. #2
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    This is like asking, which is faster - Ford or Holden, and does it even matter if all you do is drive to the supermarket two minutes down the road once a week?

    There is no "this is better than that" grand statement that we can supply as an answer here sorry.

    You show what you are doing, and we can tell you if you're doing it right.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  3. #3
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    It will depend on the compiler and the target architecture. The compiler may replace a chain of if-else with a switch. It may replace a switch with a chain of if-else. You might find the answer, then upgrade the compiler and the answer is changed.

    If you are concerned about code size, most compilers provide switches to request the smallest possible code. The compiler will then make the appropriate decisions for you. Write the code to be clear to humans, let the compiler worry about optimizing it.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  4. #4
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Not worth worrying about it because correct is better than fast.

    The decision itself ("go here, execute that, because of this") is likely to manifest itself as a set of instructions; so you have the size of those impacting the size of the executable on its own. More instructions, more code, more storage space. Then you have data itself which if its not in the executable as hard coded numbers say, like 5, which you would compare against, then it's stored in RAM as variables.

    "Which occupies more space ..." well, theoretically, as much as it takes. If your code paths are complicated, they will take up more space than code that is more straightforward. Is it worth worrying about? Not really. It is a good idea to remove dead branches of code (code paths that shouldn't be there). Whether that happens sooner or later depends on your priorities, like, getting your homework done on time.

  5. #5
    Registered User
    Join Date
    Dec 2012
    Posts
    37
    im trying to optimize my codes. im not using a licensed IDE therefore it doesnt optimize just as much as I would like it to.
    main_test_281212.c

  6. #6
    Registered User
    Join Date
    Dec 2012
    Posts
    307
    I recommend using the Pelles C IDE, simple, free and straight forward. and it seems ALOT of people on here needing help (especially from ITT) seem to be using it!!!

    I use it also, i became kind of fond of it. But also use MS VC++ for C++ mostly

  7. #7
    Registered User
    Join Date
    Dec 2012
    Posts
    37
    Quote Originally Posted by Crossfire View Post
    I recommend using the Pelles C IDE, simple, free and straight forward. and it seems ALOT of people on here needing help (especially from ITT) seem to be using it!!!

    I use it also, i became kind of fond of it. But also use MS VC++ for C++ mostly
    thanks for the recommendation Crossfire. But in this case, I havent any choice but to use this IDE

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Cases which are densely packed (like 1,2,3,4,5) should be more efficiently implemented as switch/cases. Whereas case 1, case 1000, case 1000000 would normally result in the compiler generating the corresponding if / else if chain.

    Though if you only have 2 cases, you might be better off with just if / else
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User
    Join Date
    Dec 2012
    Posts
    45
    I don't know where is the bottleneck, but...


    First, you can reorganize this:


    Code:
        key = 0;
             if ((adc > 205) && (adc < 235 )) key = 1;
        else if ((adc > 155) && (adc < 173 )) key = 2;
        else if ((adc > 80 ) && (adc < 141 )) key = 3;
        else if ((adc > 47 ) && (adc < 78  )) key = 4;
        else if ((adc > 0  ) && (adc < 15  )) key = 5;

    ...like a binary search:


    Code:
        key = 0;
        if (adc>155)
        {
            if (adc<173)
                key = 2;
            else if (adc>205 && adc<235)
                key = 1;
        }
        else if (adc<78)
        {
            if (adc>47)
                key = 4;
            else if (adc>0 && adc<15)
                key = 5;               // <--- longest path
        }
        else if (adc>80 && adc<141)
            key = 3;

    The longest path takes 5 comparisons. Though, the code is ugly :-(


    I would suggest to use 'if' instead of 'switch', just for clarity... You have few cases.


    But... wait a minute... The 'switch(state)' doesn't make any sense! The variable 'state' will always be zero at this point. It is local, you initialized it to zero, you didn't change it... Maybe you meant to make it 'static':


    static unsigned char state = 0;
    static unsigned char last_key = 0;

    For the last switch, I would suggest lookup tables:


    Code:
        static const unsigned char A[]={0xA0,0xC0,0xE8,0xD8,0xB8};
        static const unsigned char B[]={0x5F,0x3F,0x17,0x27,0x47};
        static const unsigned char C[]={0xC0,0x00};
        static const unsigned char D[]={0x3F,0x00};
        
        //...
        
        if (key>0)
        {
            if (key_event==1)
            {
                d1 = A[key-1];
                d2 = B[key-1];
            }
            else if (key_event==2 && key<3)
            {
                d1 = C[key-1];
                d2 = D[key-1];
            }
        }

    Anyway, I think that the problem is in the variable 'state'.


    And if, for some hardware limitation, your compiler were making this variable static by default, initializing it only once, then the problem could be in the initialization of other local variables.

  10. #10
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    Both a switch statement and an if...else if...else if...else sequence make a multi-way branching decision. Switch has limitations but is sometimes more concise. Consider an example program: when would it be better to rewrite this type of decision as an if...else if...else if expression? The answer probably does not have anything to do with the resulting size of the binary.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    
    #define LETTER argv[1]
    int main(int argc, char *argv[])
    {
        if (argc != 2) {
            printf("Usage: switchtest LETTER\n");
            return EXIT_FAILURE;
        }    
        char lett = tolower(LETTER[0]);
        switch(lett) {
            case 'a': case 'e': case 'i': case 'o': case 'u': case 'y':
                printf("vowel\n");
                break;
            case 'b': case 'c': case 'd': case 'f': case 'g': case 'h': case 'j':
            case 'k': case 'l': case 'm':
                printf("consonant not after m\n");
                break;
            case 'n': case 'p': case 'q': case 'r': case 's': case 't': case 'v':
            case 'w': case 'x': case 'z':
                printf("consonant after m\n");
                break;
            default:
                printf("other\n");
                break;
        }
        return EXIT_SUCCESS;
    }
    To address binary size: If you want a smaller binary, compile with size optimization and strip the binary from debugging symbols. If you want a very small binary, compile it with the "Tiny C Compiler" (tinycc). If you want the smallest possible binary size, rewrite it as an assembly program.

  11. #11
    Registered User
    Join Date
    Dec 2012
    Posts
    45
    Code:
            puts ( strchr("aeiouy",lett) ? "vowel" :
                  lett>='a' && lett<='m' ? "consonant not after m" :
                   lett>'m' && lett<='z' ? "consonant after m" :
                                           "other");
    Sorry, I couldn't resist the temptation :-)

  12. #12
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    Quote Originally Posted by comocomocomo View Post
    Sorry, I couldn't resist the temptation :-)
    Looks good. Easier to read = better.

  13. #13
    Registered User
    Join Date
    May 2012
    Posts
    505
    Quote Originally Posted by kim15 View Post
    Hi everyone,

    does anyone know the size between switch-case and if-else loops? which one is bigger in size? or in other words, which of these two occupy more space (in memory) when using?
    You've just got to try. If possible, examine the assembly code the compiler generates (-S with gcc).
    The if else ladder has the advantage that you can put the common cases at the start. For example if you're switching on "title" approximately half your sample are likely to be "Mr". Then about 1 sixth will be "Miss", "Mrs" or "Ms", you'll have about 1% Drs and then a sprinkling of Profs, Lords, Rev'ds and maybe one "Her Majesty Queen ...". So put Mr at the top of the ladder, and half the cases are resolved with a single comparison. The compiler has no way of knowing that there are millions of Mrs and only one "Her Majesty" in the entire country.
    But the switch version if often optimised with a jump table. This can be faster than comparisons.

    So it's a case of code, measure, see the assembly.
    I'm the author of MiniBasic: How to write a script interpreter and Basic Algorithms
    Visit my website for lots of associated C programming resources.
    https://github.com/MalcolmMcLean


  14. #14
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    The advantage of the switch/case is not in "size". It is that it can typically be implemented as a simple jump table (i.e. examination only once of value being tested, and a jump to a destination based on that value). The advantage is more likely to be in performance than any "size" measure. The down side is that it relies on the values tested being fixed at compile time, and it only works with integral values.

    The "size" of the comparison might only be one instruction, but the destination points (i.e. the points jumped to) have to specified in the executable, which means the net size of code the compiler emits for a switch/case can be unpredictable. Depending on the target machine, the instructions for conditional jump might have limits (eg only able to be used for a small number of jump points) which means the compiler might have to break things up (eg with the equivalent of nested if/else and switch).

    In contrast, the if() statement is general (it can be used to test anything sequentially, including pointers, floating point values). All values being compared with can be variables (not fixed at compile time). It can also be used for more complex boolean expressions (and, or, etc).


    Generally, if you are doing an integral comparison, and know all of the values being compared with, then the code will often (subjectively) be more readable and understandable using a switch/case than a lot of if/else/if with boolean expressions. Either way, depending on quality of implementation of the compiler, it can map either construct to the other. I would therefore suggest aiming for code readability than executable size, and allow the compiler (with suitable options, such as to minimimise code size) to sort out the code size issues.

    And, if it really matters, measure ensuring you use an appropriate set of compiler and linker options. And bear in mind that the code which produces the "smallest" result for one compiler (and set of compiler options) and host system will not necessarily do the same with another compiler or host system.

    Do that too soon, and all you are doing is premature optimisation. Which deserves the social stigma associated with other things that occur prematurely.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  15. #15
    Registered User caroundw5h's Avatar
    Join Date
    Oct 2003
    Posts
    751
    Quote Originally Posted by c99tutorial View Post
    Looks good. Easier to read = better.
    Are you saying his code was easier to read or yours? I've come across the use of the ternary operator like this a number of times in production code and it irritates the hell out of me. Even if it is seemingly a little more succint
    Warning: Opinions subject to change without notice

    The C Library Reference Guide
    Understand the fundamentals
    Then have some more fun

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 11
    Last Post: 08-25-2008, 12:01 PM
  2. noob question re: switch case & loops
    By scooglygoogly in forum C++ Programming
    Replies: 13
    Last Post: 08-25-2008, 11:08 AM
  3. switch case
    By Raeliean in forum C++ Programming
    Replies: 1
    Last Post: 07-04-2005, 10:29 PM
  4. Switch case
    By DeepFyre in forum C++ Programming
    Replies: 3
    Last Post: 09-25-2004, 06:29 PM
  5. Switch Case vs if else
    By WebSnozz in forum C++ Programming
    Replies: 15
    Last Post: 01-28-2003, 09:47 AM