jocull
jocull

Reputation: 21095

Compiler constants, optimizations, and performance

I have a chunk of code that frequently needs tracing information output so that clients can help debug the output - it's very math oriented.

I definitely don't want the tracing to be enabled in production for performance reasons, but having to comment it in and out frequently is becoming a hassle.

I've just setup the code like this...

using System.Diagnostics;

const bool TRACING_ENABLED = false;

//math math math....

Trace.WriteLineIf(TRACING_ENABLED, "Minimum Nitrogen Yield: " + minYieldNitrogen);
Trace.WriteLineIf(TRACING_ENABLED, "Minimum Water Yield: " + minYieldWater);
Trace.WriteLineIf(TRACING_ENABLED, "Minimum Seed Yield: " + minYieldSeed);

//more math math trace math trace math...

My question is... is this the best way to enable and disable tracing for debugging? These sorts of lines are scattered throughout the code, so I was hoping to not have to wrap blocks of if or whatever around them for housekeeping's sake.

Will the compiler optimize these lines out of the assembly since they are provided a constant of false at build time?

Thanks for your insight!

Upvotes: 2

Views: 254

Answers (4)

mhttk
mhttk

Reputation: 1696

Maybe what you can do is to write your own class

public class MyTrace 
{
     [Conditional("TRACE")]
     public static void Trace(string message)
     {
          //trace code goes here
     }
     [Conditional("DEBUG")] 
     public static void Debug(string message)
     {
          //Debug code goes here
     }
}

The advantage of this is that you can either use the conditional compiling, add configuration logic or even use a logging package like Log4Net

Of course you would use it

  ....
  MyTrace.Trace(".....");
  MyTrace.Debug(".....");
  ....

Upvotes: 0

Kris Vandermotten
Kris Vandermotten

Reputation: 10201

Instead of Trace.WriteLineIf(condition, message), use Debug.WriteLine(message).

In a Debug build, calls to this method are compiled normally. In a release build, the compiler emits no code for the call, nor for parameter evaluation. If I understand your question correctly, this is exactly what you want.

To be precise, Debug.WriteLine(message) has a [ConditionalAttribute("DEBUG")] applied to it. As a result, the compiler will emit code for a call to it, if and only if the DEBUG symbol is defined during compilation. This symbol is defined in a standard Visual Studio Debug build, but not in a Release build.

For more information, see http://msdn.microsoft.com/en-us/library/9z9k5ydz and http://msdn.microsoft.com/en-us/library/system.diagnostics.conditionalattribute.aspx.

Upvotes: 0

KeithS
KeithS

Reputation: 71563

I would take a look at the Debug.WriteLine() method as well. All of the Debug methods use Reed's Conditional attribute, but instead based on the definition of a "DEBUG" constant (which you get for free in the default Debug build config and is absent in the default Release build config). The Debug methods use the same collection of Listeners that Trace does; the idea is that you use Trace.WriteLine() for anything you want to log or show in any build of the software, and Debug.WriteLine() for additional text you want to log or show in a Debug build of the software.

Upvotes: 2

Reed Copsey
Reed Copsey

Reputation: 564403

I would use the ConditionalAttribute and a compiler flag to handle this instead.

This has the advantage of completely removing the methods from your production code - so the conditional check doesn't even occur.

Doing this, you could make your own method, such as:

[Conditional("TRACE")]
public WriteTraceLine(string message)
{
     Trace.WriteLine(message);
}

And then have a TRACE flag in your debug/non-production build settings. This will cause the method to only exist in the compiled source (including the calls) when that flag is defined.

Upvotes: 3

Related Questions