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 &
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.