```C#
public int switcher(int Input)
{
switch (Input)
{
case 0:
return 255;
case 1:
return 128;
case 2:
case 3:
return 32;
default:
return -1;
}
}
### IL compile from code
.method public
instance int32 switcher (
int32 Input
) cil managed
{
// Method begins at RVA 0x2058
// Code size 42 (0x2a)
.maxstack 2
.locals init (
[0] int32 switcher,
[1] int32
)
IL_0000: ldarg.1
IL_0001: stloc.1
IL_0002: ldloc.1
IL_0003: brtrue.s IL_000d
IL_0005: ldc.i4 255
IL_000a: stloc.0
IL_000b: br.s IL_0028
IL_000d: ldloc.1
IL_000e: ldc.i4.1
IL_000f: bne.un.s IL_0019
IL_0011: ldc.i4 128
IL_0016: stloc.0
IL_0017: br.s IL_0028
IL_0019: ldloc.1
IL_001a: ldc.i4.2
IL_001b: blt.s IL_0026
IL_001d: ldloc.1
IL_001e: ldc.i4.3
IL_001f: bgt.s IL_0026
IL_0021: ldc.i4.s 32
IL_0023: stloc.0
IL_0024: br.s IL_0028
IL_0026: ldc.i4.m1
IL_0027: stloc.0
IL_0028: ldloc.0
IL_0029: ret
} // end of method C::switcher
### What I think it should be
.method public
int32 switcher (int32 Input) cil managed
{
.maxstack 1
ldarg.0
switch(case0, case1, case2, case2)
ldc.i4.m1
ret
case0:
ldc.i4 256
ret
case1:
ldc.i4 128
ret
case2:
ldc.i4.s 32
ret
}
```
I thought op switch work like Pigeonhole sort or indexing array, should it better performance then conditioning each branch ?
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.
Compiling in debug?
e.g. dotnet build vs dotnet build -c Release
Debug sharplab.io
.method public hidebysig
instance int32 switcher (
int32 Input
) cil managed
{
// Method begins at RVA 0x2050
// Code size 56 (0x38)
.maxstack 1
.locals init (
[0] int32,
[1] int32,
[2] int32
)
IL_0000: nop
IL_0001: ldarg.1
IL_0002: stloc.1
// sequence point: hidden
IL_0003: ldloc.1
IL_0004: stloc.0
// sequence point: hidden
IL_0005: ldloc.0
IL_0006: switch (IL_001d, IL_0025, IL_002d, IL_002d)
IL_001b: br.s IL_0032
IL_001d: ldc.i4 255
IL_0022: stloc.2
IL_0023: br.s IL_0036
IL_0025: ldc.i4 128
IL_002a: stloc.2
IL_002b: br.s IL_0036
IL_002d: ldc.i4.s 32
IL_002f: stloc.2
IL_0030: br.s IL_0036
IL_0032: ldc.i4.m1
IL_0033: stloc.2
IL_0034: br.s IL_0036
IL_0036: ldloc.2
IL_0037: ret
} // end of method C::switcher
Release sharplab.io
.method public hidebysig
instance int32 switcher (
int32 Input
) cil managed
{
// Method begins at RVA 0x2050
// Code size 41 (0x29)
.maxstack 8
// sequence point: hidden
IL_0000: ldarg.1
IL_0001: switch (IL_0018, IL_001e, IL_0024, IL_0024)
IL_0016: br.s IL_0027
IL_0018: ldc.i4 255
IL_001d: ret
IL_001e: ldc.i4 128
IL_0023: ret
IL_0024: ldc.i4.s 32
IL_0026: ret
IL_0027: ldc.i4.m1
IL_0028: ret
} // end of method C::switcher
Aside you may want to file in https://github.com/dotnet/roslyn repo which is where the C# compiler is
Thanks @benaadams , I see so it was out of update VB compiler cause this, I use ILadsm and recheck with Shapelab.io but not recheck with C# code.
Function switcher(Input As int) As int
Select Case Input
Case 0
Return 255
Case 1
Return 128
Case 2 To 3
Return 32
Case Else
Return -1
End Select
End Function
Yeah the VB does generate that sharplab.io; however its because of the 2 To 3; which is using more fancy conditional switching (similar to C#'s pattern matching switches)
Changing to a fall through like the C# you originally posted; then it ends up like you expect? sharplab.io
public class C
Function switcher(Input As Integer) As Integer
Select Case Input
Case 0
Return 255
Case 1
Return 128
Case 2
Case 3
Return 32
End Select
Return -1
End Function
End Class
.method public specialname rtspecialname
instance void .ctor () cil managed
{
// Method begins at RVA 0x2050
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [System.Private.CoreLib]System.Object::.ctor()
IL_0006: ret
} // end of method C::.ctor
.method public
instance int32 switcher (
int32 Input
) cil managed
{
// Method begins at RVA 0x2058
// Code size 51 (0x33)
.maxstack 1
.locals init (
[0] int32 switcher,
[1] int32
)
IL_0000: ldarg.1
IL_0001: stloc.1
IL_0002: ldloc.1
IL_0003: switch (IL_001a, IL_0022, IL_002f, IL_002a)
IL_0018: br.s IL_002f
IL_001a: ldc.i4 255
IL_001f: stloc.0
IL_0020: br.s IL_0031
IL_0022: ldc.i4 128
IL_0027: stloc.0
IL_0028: br.s IL_0031
IL_002a: ldc.i4.s 32
IL_002c: stloc.0
IL_002d: br.s IL_0031
IL_002f: ldc.i4.m1
IL_0030: stloc.0
IL_0031: ldloc.0
IL_0032: ret
} // end of method C::switcher
} // end of class C
Aside the https://github.com/dotnet/roslyn repo is also where the VB compiler is 馃槈
Case 2 goto IL_002f, it will return -1 instead 32; VB can't go through like C#.
Ah 馃槩 sharplab.io
public class C
Function switcher(Input As Integer) As Integer
Select Case Input
Case 0
Return 255
Case 1
Return 128
Case 2
Return 32
Case 3
Return 32
Case Else
Return -1
End Select
End Function
End Class
.class public auto ansi C
extends [System.Private.CoreLib]System.Object
{
// Methods
.method public specialname rtspecialname
instance void .ctor () cil managed
{
// Method begins at RVA 0x2050
// Code size 7 (0x7)
.maxstack 8
IL_0000: ldarg.0
IL_0001: call instance void [System.Private.CoreLib]System.Object::.ctor()
IL_0006: ret
} // end of method C::.ctor
.method public
instance int32 switcher (
int32 Input
) cil managed
{
// Method begins at RVA 0x2058
// Code size 56 (0x38)
.maxstack 1
.locals init (
[0] int32 switcher,
[1] int32
)
IL_0000: ldarg.1
IL_0001: stloc.1
IL_0002: ldloc.1
IL_0003: switch (IL_001a, IL_0022, IL_002a, IL_002f)
IL_0018: br.s IL_0034
IL_001a: ldc.i4 255
IL_001f: stloc.0
IL_0020: br.s IL_0036
IL_0022: ldc.i4 128
IL_0027: stloc.0
IL_0028: br.s IL_0036
IL_002a: ldc.i4.s 32
IL_002c: stloc.0
IL_002d: br.s IL_0036
IL_002f: ldc.i4.s 32
IL_0031: stloc.0
IL_0032: br.s IL_0036
IL_0034: ldc.i4.m1
IL_0035: stloc.0
IL_0036: ldloc.0
IL_0037: ret
} // end of method C::switcher
} // end of class C