C# 开关语句 : More efficient to not use default?

标签 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";
    }

我的问题是:哪种代码会有更好的性能?上面或下面的代码,还是一样的?为什么?

我假设由于编译器优化......它们可能只是相同......但我真的不知道。

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# 编译器对其进行了优化,或者它最终只是等效的。

关于C# 开关语句 : More efficient to not use default?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9473389/

相关文章:

c# - 如何将 float 舍入到最接近的 n 倍数?

c# - 将枚举定义名称转换为字符串

Android 变量 SQLite 选择查询性能 - 任何解释?

java - Nashorn 的沙盒 Java 脚本替代品

php - 无法无错误地添加开关例程

C#内存映射文件不占用物理内存空间

c# - CreateDatabaseConnection 方法的单元测试

c# - EF 6.1 中的 LINQ 查询自定义对象最佳实践

c# - 新的 C# 8.0 switch 表达式的运算符优先级是什么?

c - 多个案例的 switch 语句