Rory Primrose

Learn from my mistakes, you don't have time to make them yourself

View project on GitHub

Carrying tracing weight you didn't know you had

Continuing on my performance testing of tracing components, there is another factor I realised that may be impacting the performance I get out of my code.

When the TraceSource.Listeners property is referenced, the collection is initialised using the application configuration. Regardless of whether there is a TraceSource configured for the provided name or what listeners are defined, there is always a default listener that is added to the configured collection of listeners. This is the System.Diagnostics.DefaultTraceListener.

All the tracing methods of this listener implementation call down to an internalWrite method that has the following implementation:

private void internalWrite(string message)
{
    if (Debugger.IsLogging())
    {
        Debugger.Log(0, null, message);
    }
    else if (message == null)
    {
        SafeNativeMethods.OutputDebugString(string.Empty);
    }
    else
    {
        SafeNativeMethods.OutputDebugString(message);
    }
}    

This is extra baggage that you probably didn’t know you had. If you want lean tracing performance and don’t need this debug trace support, the best option is to remove this listener in configuration. All you have to do is add a <clear /> element as the first item in the listeners element for each source you have defined in your configuration.

<?xml version="1.0" encoding="utf-8" ?> 
<configuration> 
    <system.diagnostics>
    <trace useGlobalLock="false" /> 
    <sources> 
        <source name="MySource" 
                switchValue="All"> 
        <listeners>
    
            <clear />
    
            <add name="ListenerName" 
                type="MyApplication.LoadTests.LoadTestTraceListener, MyApplication.LoadTests" /> 
        </listeners> 
        </source> 
    </sources>    
    </system.diagnostics> 
</configuration>     
Written on January 8, 2009