[英]C# Switch Statement: More efficient to not use default?
我在visual studio中创建了一个C#方法,它只包含一个switch语句,每个case返回一个值。 根据个人习惯,我提出了类似于以下代码的内容:
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";
}
我的问题是:哪个代码会有更好的性能? 上面或下面的代码,或者是相同的? 为什么?
我会假设因为编译器优化......它们可能只是相同......但我真的不知道。
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";
}
}
修订:看起来我应该更具体一点:编译时......一个或另一个会生成效率较低的代码吗?
我意识到性能上的差异可能微不足道......我真的很好奇。
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";
}
变为:
.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
将返回移动到默认情况:
.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
完全相同的。 没有性能差异。 为了确保代码重新生成,我将“无结果”更改为结果4。 显然,C#编译器对它进行了优化,或者它最终是等效的。
优良作法是始终在交换机的基础上包含默认情况,以防其他任何情况都无效。
这不是一个效率问题,因为如果之前的一个案例被击中 - 你的程序将不会检查任何其他情况(它相当于使用if / else if / else - 其中最后的else是默认值)。
希望这可以帮助。
使用通用字典而不是函数和switch语句,其中键是KofaxEnvironment,其值与从交换机返回的值相同。 就像是:
Dictionary<KofaxEnvironment, string>
要么
Dictionary<int, string>
我也不担心性能。 正确应该是你的第一个目标。
但是,如果您坚持使用交换机,请使用抛出异常的默认值:
default:
throw new ArgumentException("Serious programmer error!");
至于性能,开关默认值和下降到返回值之间的差异(如果有的话)可以忽略不计。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.