none
Trace.Writelineif useless string creation? RRS feed

  • Question

  • I have some code that uses Trace.WriteLineIf all over the place

    Trace.WriteLineIf(traceEngine.TraceWarning, DateTime.Now + " log some stuff");

    But this does creation and concatenation of a new string object even if TraceWarning is false.

    Isnt it better to create your own LogWriterIf(bool, string) that only adds and concats the strings if bool == true?

    I'd say its less strain on the GC which could ultimately improve performance. Is that correct or is there some magic happening with strings that all this doesnt matter?

    Friday, January 11, 2013 1:47 PM

Answers

  • Using System.Diagnostics.Trace lets you control many things about where/how tracing is done via the configuration file.  Rolling your own logger may not offer that much flexibility.

    Depending on the TraceListener, you can even have it add the date/time to each log entry.  For example, here I use the FileLogTraceListener from the VisualBasic namespace (in my C# service) to create a daily rotating log in the same folder as my service exe. traceOutputOptions="DateTime" does what it implies.

      <system.diagnostics>
        <trace autoflush="true">
          <listeners>
            <clear/>
            <add name="Rotating"
                 type="Microsoft.VisualBasic.Logging.FileLogTraceListener, Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
                 logfilecreationschedule="Daily"
                 basefilename="MyService"
                 location="ExecutableDirectory"
                 traceOutputOptions="DateTime"
                   />
          </listeners>
        </trace>
      </system.diagnostics>

    So that would eliminate the need to combine DateTime.Now + "message" everywhere.  But the root question remains.  What to do when you want to build a complex log message.

    Trace.TraceError, Trace.TraceWarning, and Trace.TraceInformation might work for you because they each have an overload that takes a variable # of parameters.

    Trace.TraceWarning("{0} some log message", DateTime.Now);
    Finally, read up on System.Diagnostics.Trace.TraceSource.  It's about 4 times more useful than the default Trace class.


    This signature unintentionally left blank.


    Monday, January 14, 2013 11:11 AM
  • Interesting, thanks for the info.

    As for the TraceWarning I created a wrapper for that too to reduce useless object creation of the "params" array if the condition is false.


    public static void WriteIf(bool b, string format, object a0, object a1)
    {
    if (b)
                    Trace.WriteLine(DateTime.Now + " " + string.Format(format, a0, a1));
    }

    public static void WriteIf(bool b, string format, object a0, object a1, object a2)
    {
    if (b)
        Trace.WriteLine(DateTime.Now + " " + string.Format(format, a0, a1, a2));
    }

    public static void WriteIf(bool b, string format, params object[] list)
    {
    if (b)
                Trace.WriteLine(DateTime.Now + " " + string.Format(format, list));
    }

    Tuesday, January 15, 2013 12:58 PM

All replies

  • Hi There,

    I am afraid that you need to change to If...else block:

    You can minimize the performance penalty of instrumenting your application by using If...Then statements instead of using WriteLineIf statements. The following two code examples send the same debugging message. However, the first example is much faster when tracing is off, because ifmySwitch.TraceError evaluates to false, you do not call WriteLine. The second example always calls WriteLineIf, even when mySwitch.TraceErroris false and no tracing output is produced. This can result in unnecessary execution of arbitrarily complex code.

    Best regards,


    Mike Feng
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, January 14, 2013 7:14 AM
    Moderator
  • You can create your own wrapper for example to Trace.WriteLine might be better in this as that prevents the concatenation of the strings if condition is false and the Trace.WriteLine method is not actually called.

    namespace My
    {
         public static class TraceWriter
         {
              public static void WriteLineIf(bool condition, string message)
              {
                   if (condition)
                   {
                       Trace.WriteLine(DateTime.Now + message);
                   }
              }
         }
    }

    But that actually don't solve the problem if someone still calls the code like below, but is better than Trace.WriteLineIf if you always want to append date in beginning. 

    TraceWriter.WriteLineIf(condition, "exception: " + ex.Message + ", stack = " + ex.StackTrace);


    • Edited by MasaSam Monday, January 14, 2013 9:27 AM
    Monday, January 14, 2013 9:24 AM
  • Using System.Diagnostics.Trace lets you control many things about where/how tracing is done via the configuration file.  Rolling your own logger may not offer that much flexibility.

    Depending on the TraceListener, you can even have it add the date/time to each log entry.  For example, here I use the FileLogTraceListener from the VisualBasic namespace (in my C# service) to create a daily rotating log in the same folder as my service exe. traceOutputOptions="DateTime" does what it implies.

      <system.diagnostics>
        <trace autoflush="true">
          <listeners>
            <clear/>
            <add name="Rotating"
                 type="Microsoft.VisualBasic.Logging.FileLogTraceListener, Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
                 logfilecreationschedule="Daily"
                 basefilename="MyService"
                 location="ExecutableDirectory"
                 traceOutputOptions="DateTime"
                   />
          </listeners>
        </trace>
      </system.diagnostics>

    So that would eliminate the need to combine DateTime.Now + "message" everywhere.  But the root question remains.  What to do when you want to build a complex log message.

    Trace.TraceError, Trace.TraceWarning, and Trace.TraceInformation might work for you because they each have an overload that takes a variable # of parameters.

    Trace.TraceWarning("{0} some log message", DateTime.Now);
    Finally, read up on System.Diagnostics.Trace.TraceSource.  It's about 4 times more useful than the default Trace class.


    This signature unintentionally left blank.


    Monday, January 14, 2013 11:11 AM
  • Interesting, thanks for the info.

    As for the TraceWarning I created a wrapper for that too to reduce useless object creation of the "params" array if the condition is false.


    public static void WriteIf(bool b, string format, object a0, object a1)
    {
    if (b)
                    Trace.WriteLine(DateTime.Now + " " + string.Format(format, a0, a1));
    }

    public static void WriteIf(bool b, string format, object a0, object a1, object a2)
    {
    if (b)
        Trace.WriteLine(DateTime.Now + " " + string.Format(format, a0, a1, a2));
    }

    public static void WriteIf(bool b, string format, params object[] list)
    {
    if (b)
                Trace.WriteLine(DateTime.Now + " " + string.Format(format, list));
    }

    Tuesday, January 15, 2013 12:58 PM
  • Good job.  Don't go too overboard with wrappers however as you're exchanging the overhead involved with object management for the overhead involved with method calls. :-)


    This signature unintentionally left blank.

    Wednesday, January 16, 2013 9:37 AM