What is happening in an “If(..||..)” and “If(…&&…)” construct internally?

后端 未结 6 1986
爱一瞬间的悲伤
爱一瞬间的悲伤 2020-12-15 18:29

I was just wondering what happens inside of an \"if OR\" and \"if AND\". I have a feeling that it\'s just syntactic sugar to use &

6条回答
  •  时光取名叫无心
    2020-12-15 18:50

    Using the compact form, the IL emitted by the C# compiler will be less verbose, resulting in less instructions to be handled at runtime. The emitted IL statements and their logic are actually the same, so there's no fancy built-in support to handle that case or some special instruction (keep in mind that you can put any expression with a boolean result into an if).

    For the compact form using the || operator (debug build):

    .method private hidebysig static void  One() cil managed
    {
      // Code size       38 (0x26)
      .maxstack  2
      .locals init ([0] bool CS$4$0000)
      IL_0000:  nop
      IL_0001:  ldsfld     bool ConsoleApplication4.Program::a
      IL_0006:  brtrue.s   IL_0019
      IL_0008:  ldsfld     bool ConsoleApplication4.Program::b
      IL_000d:  brtrue.s   IL_0019
      IL_000f:  ldsfld     bool ConsoleApplication4.Program::c
      IL_0014:  ldc.i4.0
      IL_0015:  ceq
      IL_0017:  br.s       IL_001a
      IL_0019:  ldc.i4.0
      IL_001a:  nop
      IL_001b:  stloc.0
      IL_001c:  ldloc.0
      IL_001d:  brtrue.s   IL_0025
      IL_001f:  call       void ConsoleApplication4.Program::DoSomething()
      IL_0024:  nop
      IL_0025:  ret
    } // end of method Program::One
    

    With your internal form (considering you're using else if instead of an if):

    .method private hidebysig static void  Two() cil managed
    {
      // Code size       60 (0x3c)
      .maxstack  2
      .locals init ([0] bool CS$4$0000)
      IL_0000:  nop
      IL_0001:  ldsfld     bool ConsoleApplication4.Program::a
      IL_0006:  ldc.i4.0
      IL_0007:  ceq
      IL_0009:  stloc.0
      IL_000a:  ldloc.0
      IL_000b:  brtrue.s   IL_0015
      IL_000d:  call       void ConsoleApplication4.Program::DoSomething()
      IL_0012:  nop
      IL_0013:  br.s       IL_003b
      IL_0015:  ldsfld     bool ConsoleApplication4.Program::b
      IL_001a:  ldc.i4.0
      IL_001b:  ceq
      IL_001d:  stloc.0
      IL_001e:  ldloc.0
      IL_001f:  brtrue.s   IL_0029
      IL_0021:  call       void ConsoleApplication4.Program::DoSomething()
      IL_0026:  nop
      IL_0027:  br.s       IL_003b
      IL_0029:  ldsfld     bool ConsoleApplication4.Program::c
      IL_002e:  ldc.i4.0
      IL_002f:  ceq
      IL_0031:  stloc.0
      IL_0032:  ldloc.0
      IL_0033:  brtrue.s   IL_003b
      IL_0035:  call       void ConsoleApplication4.Program::DoSomething()
      IL_003a:  nop
      IL_003b:  ret
    } // end of method Program::Two
    

    So there are way more instructions to handle all the jumps required by the additional if statements. The first form is therefore more efficient (and actually more readable :)).

    In terms of performance (each method measured 10 times with 10.000.000 iterations and removed the highest and lowest values, release build):

    Compact form: 55ms in average

    Verbose form: 56ms in average

    So there's no big difference at all.

提交回复
热议问题