简体   繁体   English

C#Switch语句:更高效不使用默认值?

[英]C# Switch Statement: More efficient to not use default?

I was creating a C# method in visual studio that contained only a switch statement where each case returned a value. 我在visual studio中创建了一个C#方法,它只包含一个switch语句,每个case返回一个值。 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. 为了确保代码重新生成,我将“无结果”更改为结果4。 Apparently the C# compiler optimizes it or it just ends up being equivalent. 显然,C#编译器对它进行了优化,或者它最终是等效的。

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). 这不是一个效率问题,因为如果之前的一个案例被击中 - 你的程序将不会检查任何其他情况(它相当于使用if / else if / else - 其中最后的else是默认值)。

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. 使用通用字典而不是函数和switch语句,其中键是KofaxEnvironment,其值与从交换机返回的值相同。 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. 至于性能,开关默认值和下降到返回值之间的差异(如果有的话)可以忽略不计。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM