编译器常量,优化和性能

时间:2012-05-25 18:29:45

标签: c# .net

我有一大堆代码经常需要跟踪信息输出,以便客户端可以帮助调试输出 - 这是非常面向数学的。

我绝对不希望出于性能原因在生产中启用跟踪,但不得不频繁地评论它是一件麻烦事。

我刚设置了这样的代码......

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

我的问题是......这是启用和禁用跟踪调试的最佳方法吗?这些类型的行分散在整个代码中,因此我希望不必为了内务管理而包裹if或其周围的块。

编译器是否会在程序集中优化这些行,因为它们在构建时提供false的常量?

感谢您的见解!

4 个答案:

答案 0 :(得分:3)

我会使用ConditionalAttribute和编译器标志来代替处理它。

这样做的好处是从生产代码中完全删除方法 - 因此甚至不会进行条件检查。

这样做,您可以制作自己的方法,例如:

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

然后在调试/非生产构建设置中有一个TRACE标志。这将导致该方法仅在定义该标志时存在于已编译的源(包括调用)中。

答案 1 :(得分:2)

我也会看一下Debug.WriteLine()方法。所有Debug方法都使用Reed的Conditional属性,而是基于“DEBUG”常量的定义(在默认的Debug构建配置中可以免费获得,并且在默认的Release构建配置中不存在)。 Debug方法使用Trace所执行的同一个Listener集合;我们的想法是,您可以将Trace.WriteLine()用于任何要在软件的任何版本中记录或显示的内容,以及Debug.WriteLine(),以获取要在软件的Debug版本中记录或显示的其他文本。 / p>

答案 2 :(得分:0)

而不是Trace.WriteLineIf(condition, message),请使用Debug.WriteLine(message)

在Debug构建中,正常编译对此方法的调用。在发布版本中,编译器不会为调用发出代码,也不会为参数评估发出代码。如果我理解你的问题,这正是你想要的。

准确地说,Debug.WriteLine(message)已应用[ConditionalAttribute("DEBUG")]。因此,当且仅当在编译期间定义了DEBUG符号时,编译器才会发出调用它的代码。此符号在标准Visual Studio Debug构建中定义,但不在发布版本中定义。

有关详细信息,请参阅http://msdn.microsoft.com/en-us/library/9z9k5ydzhttp://msdn.microsoft.com/en-us/library/system.diagnostics.conditionalattribute.aspx

答案 3 :(得分:0)

也许你能做的就是写自己的班级

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
     }
}

这样做的好处是你可以使用条件编译,添加配置逻辑甚至使用像Log4Net这样的日志包

当然你会用它

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