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

bsa*_*ara 9 c# performance switch-statement

我在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";
    }
Run Code Online (Sandbox Code Playgroud)

我的问题是:哪个代码会有更好的性能?上面或下面的代码,或者是相同的?为什么?

我会假设因为编译器优化......它们可能只是相同......但我真的不知道.

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";
        }
    }
Run Code Online (Sandbox Code Playgroud)

修订:看起来我应该更具体一点:编译时......一个或另一个会生成效率较低的代码吗?

我意识到性能上的差异可能微不足道......我真的很好奇.

Jos*_*eld 11

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";
        }
Run Code Online (Sandbox Code Playgroud)

变为:

.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
Run Code Online (Sandbox Code Playgroud)

将返回移动到默认情况:

.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
Run Code Online (Sandbox Code Playgroud)

完全相同的.没有性能差异.为了确保代码重新生成,我将"无结果"更改为结果4.显然,C#编译器对它进行了优化,或者它最终是等效的.

  • @Brandon有很多.比如ilspy (3认同)
  • +1为两种情况生成IL的努力. (3认同)
  • *ILDasm*随.NET Framework SDK一起提供.请记住,这是IL汇编代码,而不是CPU看到的代码.您可以使用SDK NGen.exe附带的工具来生成该程序集,但可能会根据硬件对其进行不同的优化. (2认同)