我应该在#if(DEBUG)中调用Debugger.Log()吗?

时间:2012-06-11 13:47:21

标签: c# visual-studio debugging logging compiler-optimization

是否需要在Debugger.Log()预处理程序指令中包含对#if (DEBUG)的调用以进行代码优化,或者在构建RELEASE配置时C#编译器是否仍会生成优化代码?

3 个答案:

答案 0 :(得分:5)

RELEASE 模式下调用没有任何类型的优化。

此呼叫存在于IL中。唯一的区别是,如果没有 DEBUGGER ,它没有任何影响。

来自文档Debugger.Log

  

如果没有附加调试器,则此方法无效。

我建议您测量应用的效果,然后选择要遵循的步骤。

如果没有显着差异(从您的应用程序的角度来看),我会按原样保留该日志。

通过这种方式,在需要的时候,您可以使用调试器附加到您的应用程序,并从日志中获取您可能需要的消息,因为Debugger.Log将在那个点工作。

答案 1 :(得分:1)

这是Debugger.Log()的声明,从Reference Source:

中检索
// Posts a message for the attached debugger.  If there is no
// debugger attached, has no effect.  The debugger may or may not
// report the message depending on its settings.
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public static extern void Log(int level, String category, String message);

请注意,该方法没有[Conditional]属性,并且它带有[MethodImplAtttribute]属性。这意味着该方法实际上是在CLR中实现的,用C ++代码编写。

无论配置如何,都将进行方法调用。您可以从SSCLI20源代码分发clr / src / vm / debugdebugger.cpp中找到该方法的实现。它使用OutputDebugString(),一个winapi函数,在调试器中显示字符串(如果已连接)。或者在像SysInternals的DbgView.exe这样的实用程序中。如果两者都不存在,那么api调用就不会做任何事情并迅速返回。你只需支付函数调用开销,少数几纳秒。

没有任何关于方法调用的优化,无论是构建Debug还是Release配置,它都会以相同的方式执行。在Release版本中访问调试信息肯定会很方便,由您来决定是否要关闭该功能。这些纳秒是否会对您的程序产生可观察的影响很难说清楚。衡量,不要假设任何事情。

答案 2 :(得分:0)

快速测试以下代码(.NET 4,Release,Any CPU)

class Program
{
    static void Main(string[] args)
    {
    #if (DEBUG)
        Debugger.Log(0, "category", "msg");
    #endif
    }
}

产生这个IL

.method private hidebysig static void Main(string[] args) cil managed
{
    .entrypoint
    .maxstack 8
    L_0000: ret 
}

正如您所看到的,Debugger.Log没有呼叫。