Blog Home  Home Feed your aggregator (RSS 2.0)  
What did you learn today? - Switch statements in IL
Phil Denoncourt's Technology Rants
 
 Friday, September 30, 2005
Switch statements in IL by phildenoncourt
Just an interesting observation that I found when looking at some code using reflector. If you have a switch statement on a string, and there is a small set of cases, (<~10), the switch is changed to a series of if/else statements. If your list is more than 10, it creates a hashtable, and inserts all the strings. Then using the expression value it find the index of the value in the hashtable and uses that as its key. I'm sure this is done for a performance reason, but I couldn't speculate as to what it was. By looking at this, it would seem to be that it is best to use enumerations, rather than hardcoded strings wherever possible.

Decompiled Switch statement with 5 cases
public string SelectILTest5(string input)
{
      string text2;
      if ((text2 = input) != null)
      {
            text2 = string.IsInterned(text2);
            if (text2 != "a1")
            {
                  if (text2 == "a2")
                  {
                        return "a2";
                  }
                  if (text2 == "a3")
                  {
                        return "a3";
                  }
                  if (text2 == "a4")
                  {
                        return "a4";
                  }
                  if (text2 == "a5")
                  {
                        return "a5";
                  }
            }
            else
            {
                  return "a1";
            }
      }
      return "";
}
Decompiled Switch statement with 15 cases(C#)
public string SelectILTest15(string input)
{
      switch (input)
      {
            case "a1":
            {
                  return "a1";
            }
            case "a2":
            {
                  return "a2";
            }
            case "a3":
            {
                  return "a3";
            }
            case "a4":
            {
                  return "a4";
            }
            case "a5":
            {
                  return "a5";
            }
            case "a6":
            {
                  return "a6";
            }
            case "a7":
            {
                  return "a7";
            }
            case "a8":
            {
                  return "a8";
            }
            case "a9":
            {
                  return "a9";
            }
            case "a10":
            {
                  return "a10";
            }
            case "a11":
            {
                  return "a11";
            }
            case "a12":
            {
                  return "a12";
            }
            case "a13":
            {
                  return "a13";
            }
            case "a14":
            {
                  return "a14";
            }
            case "a15":
            {
                  return "a15";
            }
      }
      return "";
}
Decompiled Switch statement with 15 cases (IL)
.method public hidebysig instance string SelectILTest15(string input) cil managed
{
      // Code Size: 524 byte(s)
      .maxstack 4
      .locals init (
            string text1,
            object obj1)
      L_0000: volatile 
      L_0002: ldsfld [mscorlib]System.Collections.Hashtable <PrivateImplementationDetails>::$$method0x6000015-1
      L_0007: brtrue L_0124
      L_000c: ldc.i4.s 30
      L_000e: ldc.r4 0.5
      L_0013: newobj instance void [mscorlib]System.Collections.Hashtable::.ctor(int32, float32)
      L_0018: dup 
      L_0019: ldstr "a1"
      L_001e: ldc.i4.0 
      L_001f: box int32
      L_0024: call instance void [mscorlib]System.Collections.Hashtable::Add(object, object)
      L_0029: dup 
      L_002a: ldstr "a2"
      L_002f: ldc.i4.1 
      L_0030: box int32
      L_0035: call instance void [mscorlib]System.Collections.Hashtable::Add(object, object)
      L_003a: dup 
      L_003b: ldstr "a3"
      L_0040: ldc.i4.2 
      L_0041: box int32
      L_0046: call instance void [mscorlib]System.Collections.Hashtable::Add(object, object)
      L_004b: dup 
      L_004c: ldstr "a4"
      L_0051: ldc.i4.3 
      L_0052: box int32
      L_0057: call instance void [mscorlib]System.Collections.Hashtable::Add(object, object)
      L_005c: dup 
      L_005d: ldstr "a5"
      L_0062: ldc.i4.4 
      L_0063: box int32
      L_0068: call instance void [mscorlib]System.Collections.Hashtable::Add(object, object)
      L_006d: dup 
      L_006e: ldstr "a6"
      L_0073: ldc.i4.5 
      L_0074: box int32
      L_0079: call instance void [mscorlib]System.Collections.Hashtable::Add(object, object)
      L_007e: dup 
      L_007f: ldstr "a7"
      L_0084: ldc.i4.6 
      L_0085: box int32
      L_008a: call instance void [mscorlib]System.Collections.Hashtable::Add(object, object)
      L_008f: dup 
      L_0090: ldstr "a8"
      L_0095: ldc.i4.7 
      L_0096: box int32
      L_009b: call instance void [mscorlib]System.Collections.Hashtable::Add(object, object)
      L_00a0: dup 
      L_00a1: ldstr "a9"
      L_00a6: ldc.i4.8 
      L_00a7: box int32
      L_00ac: call instance void [mscorlib]System.Collections.Hashtable::Add(object, object)
      L_00b1: dup 
      L_00b2: ldstr "a10"
      L_00b7: ldc.i4.s 9
      L_00b9: box int32
      L_00be: call instance void [mscorlib]System.Collections.Hashtable::Add(object, object)
      L_00c3: dup 
      L_00c4: ldstr "a11"
      L_00c9: ldc.i4.s 10
      L_00cb: box int32
      L_00d0: call instance void [mscorlib]System.Collections.Hashtable::Add(object, object)
      L_00d5: dup 
      L_00d6: ldstr "a12"
      L_00db: ldc.i4.s 11
      L_00dd: box int32
      L_00e2: call instance void [mscorlib]System.Collections.Hashtable::Add(object, object)
      L_00e7: dup 
      L_00e8: ldstr "a13"
      L_00ed: ldc.i4.s 12
      L_00ef: box int32
      L_00f4: call instance void [mscorlib]System.Collections.Hashtable::Add(object, object)
      L_00f9: dup 
      L_00fa: ldstr "a14"
      L_00ff: ldc.i4.s 13
      L_0101: box int32
      L_0106: call instance void [mscorlib]System.Collections.Hashtable::Add(object, object)
      L_010b: dup 
      L_010c: ldstr "a15"
      L_0111: ldc.i4.s 14
      L_0113: box int32
      L_0118: call instance void [mscorlib]System.Collections.Hashtable::Add(object, object)
      L_011d: volatile 
      L_011f: stsfld [mscorlib]System.Collections.Hashtable <PrivateImplementationDetails>::$$method0x6000015-1
      L_0124: ldarg.1 
      L_0125: dup 
      L_0126: stloc.1 
      L_0127: brfalse L_0202
      L_012c: volatile 
      L_012e: ldsfld [mscorlib]System.Collections.Hashtable <PrivateImplementationDetails>::$$method0x6000015-1
      L_0133: ldloc.1 
      L_0134: call instance object [mscorlib]System.Collections.Hashtable::get_Item(object)
      L_0139: dup 
      L_013a: stloc.1 
      L_013b: brfalse L_0202
      L_0140: ldloc.1 
      L_0141: unbox int32
      L_0146: ldind.i4 
      L_0147: switch (L_018a, L_0192, L_019a, L_01a2, L_01aa, L_01b2, L_01ba, L_01c2, L_01ca, L_01d2, L_01da, L_01e2, L_01ea, L_01f2, L_01fa)
      L_0188: br.s L_0202
      L_018a: ldstr "a1"
      L_018f: stloc.0 
      L_0190: br.s L_020a
      L_0192: ldstr "a2"
      L_0197: stloc.0 
      L_0198: br.s L_020a
      L_019a: ldstr "a3"
      L_019f: stloc.0 
      L_01a0: br.s L_020a
      L_01a2: ldstr "a4"
      L_01a7: stloc.0 
      L_01a8: br.s L_020a
      L_01aa: ldstr "a5"
      L_01af: stloc.0 
      L_01b0: br.s L_020a
      L_01b2: ldstr "a6"
      L_01b7: stloc.0 
      L_01b8: br.s L_020a
      L_01ba: ldstr "a7"
      L_01bf: stloc.0 
      L_01c0: br.s L_020a
      L_01c2: ldstr "a8"
      L_01c7: stloc.0 
      L_01c8: br.s L_020a
      L_01ca: ldstr "a9"
      L_01cf: stloc.0 
      L_01d0: br.s L_020a
      L_01d2: ldstr "a10"
      L_01d7: stloc.0 
      L_01d8: br.s L_020a
      L_01da: ldstr "a11"
      L_01df: stloc.0 
      L_01e0: br.s L_020a
      L_01e2: ldstr "a12"
      L_01e7: stloc.0 
      L_01e8: br.s L_020a
      L_01ea: ldstr "a13"
      L_01ef: stloc.0 
      L_01f0: br.s L_020a
      L_01f2: ldstr "a14"
      L_01f7: stloc.0 
      L_01f8: br.s L_020a
      L_01fa: ldstr "a15"
      L_01ff: stloc.0 
      L_0200: br.s L_020a
      L_0202: ldstr ""
      L_0207: stloc.0 
      L_0208: br.s L_020a
      L_020a: ldloc.0 
      L_020b: ret 
}
Friday, September 30, 2005 4:44:56 PM (GMT Standard Time, UTC+00:00)  #    Comments [0]   Development | DotNet  | 
Comments are closed.
Copyright © 2010 Phil Denoncourt III. All rights reserved.
DasBlog 'Portal' theme by Johnny Hughes.
Pick a theme: