I was creating a C# method in visual studio that contained only a switch statement where each case returned a value. By personal habit, I put something similar to the following code:
private string SwitchMethod(int num)
{
switch (num)
{
case 0:
return "result 1";
case 1:
return "result 2";
case 2:
return "result 3";
}
return "no result";
}
My question is this: Which code will have better performance? The code above or below, or are the same? And why?
I would assume that because of compiler optimizations...they might just be the same...but I really don't know.
private string SwitchMethod(int num)
{
switch (num)
{
case 0:
return "result 1";
case 1:
return "result 2";
case 2:
return "result 3";
default:
return "no result";
}
}
REVISION: It seems that I should be more specific: When compiled...will less efficient code be generated by one or the other?
I realize that the difference in performance may be insignificant...I'm just curious really.
public static string foo(int num)
{
switch (num)
{
case 0:
return "result 1";
case 1:
return "result 2";
case 2:
return "result 3";
}
return "no result";
}
Becomes:
.method public hidebysig static string foo(int32 num) cil managed
{
// Code size 57 (0x39)
.maxstack 1
.locals init ([0] string CS$1$0000,
[1] int32 CS$4$0001)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: stloc.1
IL_0003: ldloc.1
IL_0004: switch (
IL_0017,
IL_001f,
IL_0027)
IL_0015: br.s IL_002f
IL_0017: ldstr "result 1"
IL_001c: stloc.0
IL_001d: br.s IL_0037
IL_001f: ldstr "result 2"
IL_0024: stloc.0
IL_0025: br.s IL_0037
IL_0027: ldstr "result 3"
IL_002c: stloc.0
IL_002d: br.s IL_0037
IL_002f: ldstr "no result"
IL_0034: stloc.0
IL_0035: br.s IL_0037
IL_0037: ldloc.0
IL_0038: ret
} // end of method Program::foo
Moving the return into a default case:
.method public hidebysig static string foo(int32 num) cil managed
{
// Code size 57 (0x39)
.maxstack 1
.locals init ([0] string CS$1$0000,
[1] int32 CS$4$0001)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: stloc.1
IL_0003: ldloc.1
IL_0004: switch (
IL_0017,
IL_001f,
IL_0027)
IL_0015: br.s IL_002f
IL_0017: ldstr "result 1"
IL_001c: stloc.0
IL_001d: br.s IL_0037
IL_001f: ldstr "result 2"
IL_0024: stloc.0
IL_0025: br.s IL_0037
IL_0027: ldstr "result 3"
IL_002c: stloc.0
IL_002d: br.s IL_0037
IL_002f: ldstr "result 4"
IL_0034: stloc.0
IL_0035: br.s IL_0037
IL_0037: ldloc.0
IL_0038: ret
} // end of method Program::foo
Exactly the same. No performance difference. I changed the "no result" to result 4 just to make sure the code was regenerated. Apparently the C# compiler optimizes it or it just ends up being equivalent.
It is good practice to always include a default case at the base of a switch for situations where none of the other cases are valid.
It is not an efficiency problem because if one of the previous cases is hit - your program will not check any other cases (it is the equivalent of using if/else if/else - where the final else is the default).
Hope this helps.
Instead of a function and a switch statement you would be better off with a generic Dictionary where the key is KofaxEnvironment and the value is the same as what you're returning from the switch. Something like:
Dictionary<KofaxEnvironment, string>
or
Dictionary<int, string>
I also wouldn't worry about performance. Correctness should be your first goal.
But, if you do stick with a switch use a default that throws an exception:
default:
throw new ArgumentException("Serious programmer error!");
And as for performance, the difference (if any at all) between a switch default and falling through to a return will be negligible.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.