Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. 'switch' statement efficiency in C#

'switch' statement efficiency in C#

Scheduled Pinned Locked Moved C#
csharpc++helpquestioncode-review
14 Posts 5 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    scody
    wrote on last edited by
    #1

    I am new to C#, and have come across a situation where I need to perform different tasks based on the criteria value (string). Thought of using 'switch' statement, I know (from C++), if you order the 'case' statements according to most frequenly occuring 'cases' at the top, it will optimise the 'switch' statement (don't know for sure, but I practiced it), but in C#, order of the 'cases' doesn’t matter. In my situation, I would end up with around 50 'cases', so I would like to know if there are any other alternatives (to improve efficiency) apart from 'switch' statement? Any thought/help would be greatly appreciated.

    C P 2 Replies Last reply
    0
    • S scody

      I am new to C#, and have come across a situation where I need to perform different tasks based on the criteria value (string). Thought of using 'switch' statement, I know (from C++), if you order the 'case' statements according to most frequenly occuring 'cases' at the top, it will optimise the 'switch' statement (don't know for sure, but I practiced it), but in C#, order of the 'cases' doesn’t matter. In my situation, I would end up with around 50 'cases', so I would like to know if there are any other alternatives (to improve efficiency) apart from 'switch' statement? Any thought/help would be greatly appreciated.

      C Offline
      C Offline
      Christian Graus
      wrote on last edited by
      #2

      scody wrote:

      but in C#, order of the 'cases' doesn’t matter.

      What on earth makes you think that ? Yes, put your most common cases near the top, as they will get checked first, the MSIL for a switch is no different to a bunch of if/then/else statements. switch is just more human readable.

      Christian Graus No longer a Microsoft MVP, but still happy to answer your questions.

      S L 2 Replies Last reply
      0
      • C Christian Graus

        scody wrote:

        but in C#, order of the 'cases' doesn’t matter.

        What on earth makes you think that ? Yes, put your most common cases near the top, as they will get checked first, the MSIL for a switch is no different to a bunch of if/then/else statements. switch is just more human readable.

        Christian Graus No longer a Microsoft MVP, but still happy to answer your questions.

        S Offline
        S Offline
        scody
        wrote on last edited by
        #3

        Christian Graus wrote:

        What on earth makes you think that ?

        One of the books on C# stated "One intriguing point about the switch statement in C# is that the order of the cases doesn’t matter—we can even put the default case first!" This statement made me think..

        G 1 Reply Last reply
        0
        • S scody

          Christian Graus wrote:

          What on earth makes you think that ?

          One of the books on C# stated "One intriguing point about the switch statement in C# is that the order of the cases doesn’t matter—we can even put the default case first!" This statement made me think..

          G Offline
          G Offline
          Guffa
          wrote on last edited by
          #4

          scody wrote:

          One of the books on C# stated "One intriguing point about the switch statement in C# is that the order of the cases doesn’t matter—we can even put the default case first!" This statement made me think..

          That statement is talking about the syntax of the switch construct, not the performance. The performance is a whole different matter: The order of the case labels matters if you only have five of less of them. Then you should place the most commonly used ones first. If you have more than five case labels the switch uses a hash table, so then the order of the case labels doesn't matter at all. (I determined this by performance testing a switch in C# 3 (VS2008) targetting framework 3.5. The implementation may of course differ in older versions of the compiler or framework, but I doubt that this was ever any different.)

          Despite everything, the person most likely to be fooling you next is yourself.

          L C 2 Replies Last reply
          0
          • C Christian Graus

            scody wrote:

            but in C#, order of the 'cases' doesn’t matter.

            What on earth makes you think that ? Yes, put your most common cases near the top, as they will get checked first, the MSIL for a switch is no different to a bunch of if/then/else statements. switch is just more human readable.

            Christian Graus No longer a Microsoft MVP, but still happy to answer your questions.

            L Offline
            L Offline
            leppie
            wrote on last edited by
            #5

            Christian Graus wrote:

            scody wrote: but in C#, order of the 'cases' doesn’t matter. What on earth makes you think that ?

            What on earth makes you think it does matter?

            Christian Graus wrote:

            the MSIL for a switch is no different to a bunch of if/then/else statements

            The MSIL for a switch is jumptable, not if/else branching. For integral types, the target offset is simply computed (not sure what happens internally), in your typical state machine fashion. For strings the behaviour could be different.

            xacc.ide - now with TabsToSpaces support
            IronScheme - 1.0 alpha 4a out now (29 May 2008)

            G 1 Reply Last reply
            0
            • G Guffa

              scody wrote:

              One of the books on C# stated "One intriguing point about the switch statement in C# is that the order of the cases doesn’t matter—we can even put the default case first!" This statement made me think..

              That statement is talking about the syntax of the switch construct, not the performance. The performance is a whole different matter: The order of the case labels matters if you only have five of less of them. Then you should place the most commonly used ones first. If you have more than five case labels the switch uses a hash table, so then the order of the case labels doesn't matter at all. (I determined this by performance testing a switch in C# 3 (VS2008) targetting framework 3.5. The implementation may of course differ in older versions of the compiler or framework, but I doubt that this was ever any different.)

              Despite everything, the person most likely to be fooling you next is yourself.

              L Offline
              L Offline
              leppie
              wrote on last edited by
              #6

              Guffa wrote:

              The order of the case labels matters if you only have five of less of them. Then you should place the most commonly used ones first. If you have more than five case labels the switch uses a hash table, so then the order of the case labels doesn't matter at all.

              References?

              xacc.ide - now with TabsToSpaces support
              IronScheme - 1.0 alpha 4a out now (29 May 2008)

              1 Reply Last reply
              0
              • G Guffa

                scody wrote:

                One of the books on C# stated "One intriguing point about the switch statement in C# is that the order of the cases doesn’t matter—we can even put the default case first!" This statement made me think..

                That statement is talking about the syntax of the switch construct, not the performance. The performance is a whole different matter: The order of the case labels matters if you only have five of less of them. Then you should place the most commonly used ones first. If you have more than five case labels the switch uses a hash table, so then the order of the case labels doesn't matter at all. (I determined this by performance testing a switch in C# 3 (VS2008) targetting framework 3.5. The implementation may of course differ in older versions of the compiler or framework, but I doubt that this was ever any different.)

                Despite everything, the person most likely to be fooling you next is yourself.

                C Offline
                C Offline
                Christian Graus
                wrote on last edited by
                #7

                Guffa wrote:

                If you have more than five case labels the switch uses a hash table, so then the order of the case labels doesn't matter at all.

                Wow - I did not know that. I doubt very much that has always been the case, the C# 1.0 book I read delved into MSIL a lot and never mentioned it. I worked out this week that the TryParse methods arrived in 2.0, I suspect that sort of stuff did not come before 2.0 at least.

                Christian Graus No longer a Microsoft MVP, but still happy to answer your questions.

                L 1 Reply Last reply
                0
                • C Christian Graus

                  Guffa wrote:

                  If you have more than five case labels the switch uses a hash table, so then the order of the case labels doesn't matter at all.

                  Wow - I did not know that. I doubt very much that has always been the case, the C# 1.0 book I read delved into MSIL a lot and never mentioned it. I worked out this week that the TryParse methods arrived in 2.0, I suspect that sort of stuff did not come before 2.0 at least.

                  Christian Graus No longer a Microsoft MVP, but still happy to answer your questions.

                  L Offline
                  L Offline
                  leppie
                  wrote on last edited by
                  #8

                  Christian Graus wrote:

                  Wow - I did not know that.

                  Yeah I just tested it. The claim is BS. It creates the same construct regardless of the number of cases. It will reorganize cases to make the lookup more efficient, but there is NO hashtable!

                  xacc.ide - now with TabsToSpaces support
                  IronScheme - 1.0 alpha 4a out now (29 May 2008)

                  G 1 Reply Last reply
                  0
                  • L leppie

                    Christian Graus wrote:

                    scody wrote: but in C#, order of the 'cases' doesn’t matter. What on earth makes you think that ?

                    What on earth makes you think it does matter?

                    Christian Graus wrote:

                    the MSIL for a switch is no different to a bunch of if/then/else statements

                    The MSIL for a switch is jumptable, not if/else branching. For integral types, the target offset is simply computed (not sure what happens internally), in your typical state machine fashion. For strings the behaviour could be different.

                    xacc.ide - now with TabsToSpaces support
                    IronScheme - 1.0 alpha 4a out now (29 May 2008)

                    G Offline
                    G Offline
                    Guffa
                    wrote on last edited by
                    #9

                    leppie wrote:

                    The MSIL for a switch is jumptable, not if/else branching.

                    If you have five or less case labels, the code generated uses if/else logic. You can easily determine this by testing the performance, and see the difference between selecting different values.

                    Despite everything, the person most likely to be fooling you next is yourself.

                    1 Reply Last reply
                    0
                    • L leppie

                      Christian Graus wrote:

                      Wow - I did not know that.

                      Yeah I just tested it. The claim is BS. It creates the same construct regardless of the number of cases. It will reorganize cases to make the lookup more efficient, but there is NO hashtable!

                      xacc.ide - now with TabsToSpaces support
                      IronScheme - 1.0 alpha 4a out now (29 May 2008)

                      G Offline
                      G Offline
                      Guffa
                      wrote on last edited by
                      #10

                      leppie wrote:

                      It creates the same construct regardless of the number of cases.

                      Not at all. Here is the generated code for a switch containing five case labels and one containing six case labels. Do you see the fundamental difference?

                      00000084 mov esi,dword ptr [ebp-44h]
                      00000087 test esi,esi
                      00000089 je 000000ED
                      0000008b mov edx,dword ptr ds:[02C33098h]
                      00000091 mov ecx,esi
                      00000093 call 7795C574
                      00000098 mov edi,eax
                      0000009a test edi,edi
                      0000009c jne 000000ED
                      0000009e mov edx,dword ptr ds:[02C3309Ch]
                      000000a4 mov ecx,esi
                      000000a6 call 7795C574
                      000000ab mov edi,eax
                      000000ad test edi,edi
                      000000af jne 000000ED
                      000000b1 mov edx,dword ptr ds:[02C330A0h]
                      000000b7 mov ecx,esi
                      000000b9 call 7795C574
                      000000be mov edi,eax
                      000000c0 test edi,edi
                      000000c2 jne 000000ED
                      000000c4 mov edx,dword ptr ds:[02C330A4h]
                      000000ca mov ecx,esi
                      000000cc call 7795C574
                      000000d1 mov edi,eax
                      000000d3 test edi,edi
                      000000d5 jne 000000ED
                      000000d7 mov edx,dword ptr ds:[02C330A8h]
                      000000dd mov ecx,esi
                      000000df call 7795C574
                      000000e4 mov edi,eax
                      000000e6 test edi,edi
                      000000e8 jne 000000ED
                      000000ea nop
                      000000eb jmp 000000ED

                      0000008a mov ebx,dword ptr [ebp-44h]
                      0000008d test ebx,ebx
                      0000008f je 00000148
                      00000095 cmp dword ptr ds:[02B284BCh],0
                      0000009c jne 0000011F
                      000000a2 mov ecx,7913386Ch
                      000000a7 call FCAC0A5C
                      000000ac mov esi,eax
                      000000ae mov ecx,esi
                      000000b0 mov edx,6
                      000000b5 call 75929474
                      000000ba push 0
                      000000bc mov edx,dword ptr ds:[02B23098h]
                      000000c2 mov ecx,esi
                      000000c4 call 75954260
                      000000c9 push 1
                      000000cb mov edx,dword ptr ds:[02B2309Ch]
                      000000d1 mov ecx,esi
                      000000d3 call 75954260
                      000000d8 push 2
                      000000da mov edx,dword ptr ds:[02B230A0h]
                      000000e0 mov ecx,esi
                      000000e2 call 75954260
                      000000e7 push 3
                      000000e9 mov edx,dword ptr ds:[02B230A4h]
                      000000ef mov ecx,esi
                      000000f1 call 75954260
                      000000f6 pu

                      L 1 Reply Last reply
                      0
                      • G Guffa

                        leppie wrote:

                        It creates the same construct regardless of the number of cases.

                        Not at all. Here is the generated code for a switch containing five case labels and one containing six case labels. Do you see the fundamental difference?

                        00000084 mov esi,dword ptr [ebp-44h]
                        00000087 test esi,esi
                        00000089 je 000000ED
                        0000008b mov edx,dword ptr ds:[02C33098h]
                        00000091 mov ecx,esi
                        00000093 call 7795C574
                        00000098 mov edi,eax
                        0000009a test edi,edi
                        0000009c jne 000000ED
                        0000009e mov edx,dword ptr ds:[02C3309Ch]
                        000000a4 mov ecx,esi
                        000000a6 call 7795C574
                        000000ab mov edi,eax
                        000000ad test edi,edi
                        000000af jne 000000ED
                        000000b1 mov edx,dword ptr ds:[02C330A0h]
                        000000b7 mov ecx,esi
                        000000b9 call 7795C574
                        000000be mov edi,eax
                        000000c0 test edi,edi
                        000000c2 jne 000000ED
                        000000c4 mov edx,dword ptr ds:[02C330A4h]
                        000000ca mov ecx,esi
                        000000cc call 7795C574
                        000000d1 mov edi,eax
                        000000d3 test edi,edi
                        000000d5 jne 000000ED
                        000000d7 mov edx,dword ptr ds:[02C330A8h]
                        000000dd mov ecx,esi
                        000000df call 7795C574
                        000000e4 mov edi,eax
                        000000e6 test edi,edi
                        000000e8 jne 000000ED
                        000000ea nop
                        000000eb jmp 000000ED

                        0000008a mov ebx,dword ptr [ebp-44h]
                        0000008d test ebx,ebx
                        0000008f je 00000148
                        00000095 cmp dword ptr ds:[02B284BCh],0
                        0000009c jne 0000011F
                        000000a2 mov ecx,7913386Ch
                        000000a7 call FCAC0A5C
                        000000ac mov esi,eax
                        000000ae mov ecx,esi
                        000000b0 mov edx,6
                        000000b5 call 75929474
                        000000ba push 0
                        000000bc mov edx,dword ptr ds:[02B23098h]
                        000000c2 mov ecx,esi
                        000000c4 call 75954260
                        000000c9 push 1
                        000000cb mov edx,dword ptr ds:[02B2309Ch]
                        000000d1 mov ecx,esi
                        000000d3 call 75954260
                        000000d8 push 2
                        000000da mov edx,dword ptr ds:[02B230A0h]
                        000000e0 mov ecx,esi
                        000000e2 call 75954260
                        000000e7 push 3
                        000000e9 mov edx,dword ptr ds:[02B230A4h]
                        000000ef mov ecx,esi
                        000000f1 call 75954260
                        000000f6 pu

                        L Offline
                        L Offline
                        leppie
                        wrote on last edited by
                        #11

                        Eish, we are really splitting micro-bits here! ;P What are you case labels for either case? IMO, this JIT is way too low level to care about. Maybe doing the native layout, etc for more than 5 cases are a bit expensive. I was looking at MSIL level though, so I didnt really know (and still dont care) about what happens under those covers (but good to know none the less) :) Thanks leppie

                        xacc.ide - now with TabsToSpaces support
                        IronScheme - 1.0 alpha 4a out now (29 May 2008)

                        G 1 Reply Last reply
                        0
                        • L leppie

                          Eish, we are really splitting micro-bits here! ;P What are you case labels for either case? IMO, this JIT is way too low level to care about. Maybe doing the native layout, etc for more than 5 cases are a bit expensive. I was looking at MSIL level though, so I didnt really know (and still dont care) about what happens under those covers (but good to know none the less) :) Thanks leppie

                          xacc.ide - now with TabsToSpaces support
                          IronScheme - 1.0 alpha 4a out now (29 May 2008)

                          G Offline
                          G Offline
                          Guffa
                          wrote on last edited by
                          #12

                          leppie wrote:

                          Eish, we are really splitting micro-bits here!

                          Yes, but it can at least be good to know that if you have a lot of case labels, you don't have to try to order them for performance.

                          leppie wrote:

                          What are you case labels for either case?

                          Just labels with strings and no code, so that it tests the performance of the switch only:

                          switch (selection) {
                          case "00":
                          case "01":
                          case "02":
                          case "03":
                          case "04":
                          case "05":
                          default: break;
                          }

                          (I tested it with code in the cases also, so that I know that it behaves in the same manner.) My results for a 10000000 loop for each case label, with switches having five and six case labels:

                          00 : 105 ms.
                          01 : 205 ms.
                          02 : 303 ms.
                          03 : 421 ms.
                          04 : 500 ms.

                          00 : 602 ms.
                          01 : 605 ms.
                          02 : 589 ms.
                          03 : 622 ms.
                          04 : 615 ms.
                          05 : 577 ms.

                          There is definitely a measurable performance difference for the first labels in the shorter switch, but even 60 ns. isn't much to whine about. :)

                          Despite everything, the person most likely to be fooling you next is yourself.

                          L 1 Reply Last reply
                          0
                          • G Guffa

                            leppie wrote:

                            Eish, we are really splitting micro-bits here!

                            Yes, but it can at least be good to know that if you have a lot of case labels, you don't have to try to order them for performance.

                            leppie wrote:

                            What are you case labels for either case?

                            Just labels with strings and no code, so that it tests the performance of the switch only:

                            switch (selection) {
                            case "00":
                            case "01":
                            case "02":
                            case "03":
                            case "04":
                            case "05":
                            default: break;
                            }

                            (I tested it with code in the cases also, so that I know that it behaves in the same manner.) My results for a 10000000 loop for each case label, with switches having five and six case labels:

                            00 : 105 ms.
                            01 : 205 ms.
                            02 : 303 ms.
                            03 : 421 ms.
                            04 : 500 ms.

                            00 : 602 ms.
                            01 : 605 ms.
                            02 : 589 ms.
                            03 : 622 ms.
                            04 : 615 ms.
                            05 : 577 ms.

                            There is definitely a measurable performance difference for the first labels in the shorter switch, but even 60 ns. isn't much to whine about. :)

                            Despite everything, the person most likely to be fooling you next is yourself.

                            L Offline
                            L Offline
                            leppie
                            wrote on last edited by
                            #13

                            so we are talking 50 nanoseconds here per iteration. ;P

                            xacc.ide - now with TabsToSpaces support
                            IronScheme - 1.0 alpha 4a out now (29 May 2008)

                            1 Reply Last reply
                            0
                            • S scody

                              I am new to C#, and have come across a situation where I need to perform different tasks based on the criteria value (string). Thought of using 'switch' statement, I know (from C++), if you order the 'case' statements according to most frequenly occuring 'cases' at the top, it will optimise the 'switch' statement (don't know for sure, but I practiced it), but in C#, order of the 'cases' doesn’t matter. In my situation, I would end up with around 50 'cases', so I would like to know if there are any other alternatives (to improve efficiency) apart from 'switch' statement? Any thought/help would be greatly appreciated.

                              P Offline
                              P Offline
                              PIEBALDconsult
                              wrote on last edited by
                              #14

                              Or you could try a Dictionary of delegates. It may at least help with maintenance issues.

                              1 Reply Last reply
                              0
                              Reply
                              • Reply as topic
                              Log in to reply
                              • Oldest to Newest
                              • Newest to Oldest
                              • Most Votes


                              • Login

                              • Don't have an account? Register

                              • Login or register to search.
                              • First post
                                Last post
                              0
                              • Categories
                              • Recent
                              • Tags
                              • Popular
                              • World
                              • Users
                              • Groups