Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does the C# compiler remove an if that encapsulates a debug.writeline

I have a piece of code like this:

if (state != "Ok") {      Debug.WriteLine($"Error occured: {state}, {moreInfo}"); } 

Does the compiler optimize this away if i make a release build? Or does the evaluation stay and thus costing some processing time?

like image 376
fly3rbug Avatar asked Dec 14 '16 12:12

fly3rbug


1 Answers

Yes, it does, at least for the Debug call. I can't see here if the JIT compiler also removed the evaluation of the if, but I guess it does since the equation doesn't have any side effects.

However, you are better of keeping it safe by calling Debug.WriteLineIf, which doesn't depend on the JIT compiler to remove the evaluation.

For completeness the proof for the compiler to remove the Debug.WriteLine.


The code in Release build:

.method public hidebysig static void  Main(string[] args) cil managed {   .entrypoint   // Code size       17 (0x11)   .maxstack  8   IL_0000:  call       string [mscorlib]System.Console::ReadLine()   IL_0005:  ldstr      "Ok"   IL_000a:  call       bool [mscorlib]System.String::op_Inequality(string,                                                                    string)   IL_000f:  pop   IL_0010:  ret } // end of method Program::Main 

Code in Debug build:

.method public hidebysig static void  Main(string[] args) cil managed {   .entrypoint   // Code size       42 (0x2a)   .maxstack  2   .locals init ([0] string state,            [1] bool V_1)   IL_0000:  nop   IL_0001:  call       string [mscorlib]System.Console::ReadLine()   IL_0006:  stloc.0   IL_0007:  ldloc.0   IL_0008:  ldstr      "Ok"   IL_000d:  call       bool [mscorlib]System.String::op_Inequality(string,                                                                    string)   IL_0012:  stloc.1   IL_0013:  ldloc.1   IL_0014:  brfalse.s  IL_0029   IL_0016:  nop   IL_0017:  ldstr      "Error occured: {0}"   IL_001c:  ldloc.0   IL_001d:  call       string [mscorlib]System.String::Format(string,                                                               object)   IL_0022:  call       void [System]System.Diagnostics.Debug::WriteLine(string)   IL_0027:  nop   IL_0028:  nop   IL_0029:  ret } // end of method Program::Main 

As you see the Release mode has no call to Debug.WriteLine, where the Debug mode does.

like image 156
Patrick Hofman Avatar answered Sep 28 '22 07:09

Patrick Hofman