C#elseif vs.else{if}速度

C#elseif vs.else{if}速度,c#,performance,if-statement,C#,Performance,If Statement,以下哪一项更快 if {...} else if{...} 或 如果编译成一条语句或编译成与第二条语句相同的逻辑,则是else吗?如果基本相同,则是else。如果您选择以后一种方式编写,编译器将生成完全相同的IL代码,但我相信这在很大程度上取决于您的构建设置,以及项目是为调试还是发布而构建,启用了哪些优化等。一般来说,它们在所有目的和目的上都应该相同,你可以这样对待他们。我的建议是你写哪个更清楚 就像索内尔·格努尔在评论中所说的那样,你总是可以简单地测试这个问题。否则如果基本相同的话。如果您选

以下哪一项更快

if {...}
else if{...}


如果编译成一条语句或编译成与第二条语句相同的逻辑,则是
else吗?

如果
基本相同,则是else。如果您选择以后一种方式编写,编译器将生成完全相同的IL代码,但我相信这在很大程度上取决于您的构建设置,以及项目是为调试还是发布而构建,启用了哪些优化等。一般来说,它们在所有目的和目的上都应该相同,你可以这样对待他们。我的建议是你写哪个更清楚


就像索内尔·格努尔在评论中所说的那样,你总是可以简单地测试这个问题。

否则如果
基本相同的话。如果您选择以后一种方式编写,编译器将生成完全相同的IL代码,但我相信这在很大程度上取决于您的构建设置,以及项目是为调试还是发布而构建,启用了哪些优化等。一般来说,它们在所有目的和目的上都应该相同,你可以这样对待他们。我的建议是你写哪个更清楚


正如Soner Gönül在评论中所说,您可以对其进行简单的测试。

我不能说编译后的代码是什么,但让我们这样看:

您可以使用包含多行的if条件

if 
{
   // multiple statements
}
else 
{
   // multiple statements
}
您还可以使用包含单行语句的if条件

if 
   // one line statement
else
   // one line statement
现在,假设else后面的if条件是一行语句

if 
  ...
else 
  if ()
  {

  }

我不能说编译后的代码是什么,但让我们这样看:

您可以使用包含多行的if条件

if 
{
   // multiple statements
}
else 
{
   // multiple statements
}
您还可以使用包含单行语句的if条件

if 
   // one line statement
else
   // one line statement
现在,假设else后面的if条件是一行语句

if 
  ...
else 
  if ()
  {

  }
考虑

if(condition1)
{
      // code
}
else
{
     if(condition2)
     {
         // code
     }
}
在上面的代码中,如果condition1为false,则执行将转到else。然后在else中,它将再次检查条件2是否为真

现在考虑下面的代码

if(condition1)
{
    // code
}
else if(condition2)
{
    // code        
}
在上面的代码中,若条件1为false,则只有当条件2为true时,控件才会转到if-else

所以从参考

因为在IF-ELSE IF-ELSE树中只执行一条语句。ELSE-IF可以提供一个选项,在前面的表达式为FALSE时执行其他内容,这非常有用,因为ELSE-IF的语句仅在其表达式求值为TRUE时才会执行,而ELSE-IF的语句在其表达式求值为FALSE时始终会执行。

请考虑

if(condition1)
{
      // code
}
else
{
     if(condition2)
     {
         // code
     }
}
在上面的代码中,如果condition1为false,则执行将转到else。然后在else中,它将再次检查条件2是否为真

现在考虑下面的代码

if(condition1)
{
    // code
}
else if(condition2)
{
    // code        
}
在上面的代码中,若条件1为false,则只有当条件2为true时,控件才会转到if-else

所以从参考


因为在IF-ELSE IF-ELSE树中只执行一条语句。ELSE-IF可以提供一个选项,在前面的表达式为FALSE时执行其他语句,这非常有用,因为ELSE-IF语句仅在其表达式计算为TRUE时才会执行,而ELSE-IF语句在其表达式计算为FALSE时始终会执行。

在结果

C#中没有
elseif
,因此
else if
只是包含另一个
if
else

if
else
后面跟着一条语句时,不需要括号,可以在语句周围的任意位置添加括号。您可以堆叠几个括号,结果仍然相同:

{
  if (something) {
    {
      {
        // do something
      }
    }
  } else {
    {
      {
        {
          if (something) {
            {
              // do something
            }
          }
        }
      }
    }
  }
}

通过添加括号可以看到的唯一区别是,它创建了一个作用域,但仅由编译器用于确定标识符的作用域,编译后的代码仍然是相同的。

结果没有差异

C#中没有
elseif
,因此
else if
只是包含另一个
if
else

if
else
后面跟着一条语句时,不需要括号,可以在语句周围的任意位置添加括号。您可以堆叠几个括号,结果仍然相同:

{
  if (something) {
    {
      {
        // do something
      }
    }
  } else {
    {
      {
        {
          if (something) {
            {
              // do something
            }
          }
        }
      }
    }
  }
}

通过添加括号,您可以看到的唯一区别是它创建了一个作用域,但编译器仅使用该作用域来确定标识符的作用域,编译后的代码仍然是相同的。

我在C#console应用程序中编写了这些方法,并使用Telerik JustDecompile分析了生成的程序集的IL

private int Method1(int x)
{
    int y = 0;
    if (x == 0)
    {
        y = 10;
    }
    else if (x == 1)
    {
        y = 20;
    }
    return y;
}

private int Method2(int x)
{
    int y = 0;
    if (x == 0)
    {
        y = 10;
    }
    else
    {
        if (x == 1)
        {
            y = 20;
        }
    }
    return y;
}
两种方法的IL结果相同

.method private hidebysig 
    instance int32 Method1 (
        int32 x
    ) cil managed 
{
    .locals init (
        [0] int32 y
    )

    IL_0000: ldc.i4.0
    IL_0001: stloc.0
    IL_0002: ldarg.1
    IL_0003: brtrue.s IL_000a

    IL_0005: ldc.i4.s 10
    IL_0007: stloc.0
    IL_0008: br.s IL_0011

    IL_000a: ldarg.1
    IL_000b: ldc.i4.1
    IL_000c: bne.un.s IL_0011

    IL_000e: ldc.i4.s 20
    IL_0010: stloc.0

    IL_0011: ldloc.0
    IL_0012: ret
}

编辑:在我的第一个回答中,我告诉我在生成的IL代码中发现了一些额外的Nop指令,但这是因为我在调试模式下编译了我的应用程序。在发布模式下,没有区别。

我在C#console应用程序中编写了这些方法,并使用Telerik JustDecompile分析了生成的程序集的IL

private int Method1(int x)
{
    int y = 0;
    if (x == 0)
    {
        y = 10;
    }
    else if (x == 1)
    {
        y = 20;
    }
    return y;
}

private int Method2(int x)
{
    int y = 0;
    if (x == 0)
    {
        y = 10;
    }
    else
    {
        if (x == 1)
        {
            y = 20;
        }
    }
    return y;
}
两种方法的IL结果相同

.method private hidebysig 
    instance int32 Method1 (
        int32 x
    ) cil managed 
{
    .locals init (
        [0] int32 y
    )

    IL_0000: ldc.i4.0
    IL_0001: stloc.0
    IL_0002: ldarg.1
    IL_0003: brtrue.s IL_000a

    IL_0005: ldc.i4.s 10
    IL_0007: stloc.0
    IL_0008: br.s IL_0011

    IL_000a: ldarg.1
    IL_000b: ldc.i4.1
    IL_000c: bne.un.s IL_0011

    IL_000e: ldc.i4.s 20
    IL_0010: stloc.0

    IL_0011: ldloc.0
    IL_0012: ret
}

编辑:在我的第一个回答中,我告诉我在生成的IL代码中发现了一些额外的Nop指令,但这是因为我在调试模式下编译了我的应用程序。在发布模式下,没有区别。

编写一个测试程序,查看生成的
IL代码。
。如果你有两匹马,你想知道这两匹马中哪一匹跑得更快,那就比赛你的马。性能将是相同的;所有“if”、“else”、“switch”?“等将在最后编译为“JZ”、“JNZ”等汇编程序instructions@DmitryBychenko:
switch
可以编译成相同的IL,但是它比
if-else
块快,因为一个值与预期的常量进行比较。@Soner无意冒犯JNF,但是考虑到他问的问题的程度,告诉他自己去测试可能会导致错误的结果,直接测试一个,然后测试另一个