Performance impact of DefaultTraceListener
Asked Answered
T

2

8

When using System.Diagnostics tracing, is there a significant (measurable) performance impact on not removing the "Default" trace listener on a production ASP.NET application in release mode, with the TRACE constant defined at compilation time but with no debugger attached at runtime?

To clarify, the question is about additional impact of the "Default" trace listener on an application that is using other trace listeners, not about alternatives to System.Diagnostics tracing.

Are there any measures of the impact of the Default trace listener when there is no debugger attached? Are there any benchmarks already done of the impact in production of leaving out the "remove" element from a code such as this:

<configuration>
<system.diagnostics>
  <trace autoflush="false" indentsize="4">
    <listeners>
      <remove name="Default" />
      <add name="myListener"  type="System.Diagnostics.TextWriterTraceListener"    initializeData="c:\myListener.log" />
    </listeners>
  </trace>
</system.diagnostics>
</configuration>

This question is different from .NET Tracing: What is the “Default” listener? in the sense that that other question was focused on the impact of the Default listener when running under Visual Studio and updating a debugging UI, and this question is focused on release code in a production environment.

Tithable answered 27/2, 2013 at 18:43 Comment(4)
So you measured this on your particular machine and operating system? What did you find out? You didn't bother to try it?Mahoney
Since the common practice is to recommend to remove that line, I'm looking for people to help me find the published measurements that recommendation is based on. I'm assuming there is already a published benchmark and concocting my own would add little to the discussion.Tithable
There are a lot of things wrong with this question. Not only did you ask it so poorly that you got the completely wrong answer, you also gave no justification why you'd consider not following a recommended practice. And you've been waiting 4 hours for something you could have tested yourself in 10 minutes, getting a reliable result. Nobody is going to tell you how long OutputDebugString takes on your machine.Mahoney
@Hans Passant, thank you for your concern and your opinion. I didn't want to rely on my own testing because it would be biased by my assumptions. In the end I got an excellent answer that pointed me in a different and better direction.Tithable
W
14

There can be a significant impact in performance if tracing is left on using the default trace listener.

If you want production ready performance tracing, I would strongly recommend using the EventSource class from .NET 4.5 instead of the tracing method. This works with PerfView by creating an ETW event source, and has almost no impact on runtimes, even when you output tracing information in production.


Leaving the default listener in place causes the framework to log calls via OutputDebugString. This can have a significant impact on performance, even in a release build without a debugger.

Willingham answered 27/2, 2013 at 18:46 Comment(3)
Thank you for your answer, but my question was somewhat vague and mislead you. I'm not asking about the most efficient way to implement performance counters. I'm interested in the potential impact of not removing the "Default" trace listener in an application that uses other listeners with System.Diagnostic and has no debugger attached at runtime. I might create other questions about the suitability of ETW for the use case I have in mind.Tithable
@FernandoCorreia I edited to show that - My original post still was correct: there is a significant impact, but now I added something explaining a bit more as to why.Willingham
@FernandoCorreia I mentioned ETW because this has nearly 0 impact, even when you enable logging, which is why the framework itself uses it throughout and leaves the diagnostics in place in production.Willingham
A
0

The DefaultTraceListener itself is "quite fast" - as in, it is normally not noticeable with all but the most wanton usage. However, in conjunction with the Trace.UseGlobalLock it can have a significant impact on a heavily loaded system.

Today our systems were experiencing excessive CPU load and context switching (which is another problem) .. and something unexpected happened which compounded the problem to the point where work effectively halted:

Heavily threaded code started blocking for upwards of 12 seconds (!!) on the Trace.WriteLine as it had to acquire the lock over the "trivial" work in the DefaultTraceListener.

While the UseGlobalLock is applied even if there is no trace listener it is effectively a lock with nothing inside - vs. a lock with a little tiny bit of something inside that can snowball on an already loaded system with many threads.

The immediate fixes are to disable UseGlobalLock (this has other side-effects [disclaimer: another post of mine]) and to remove the DefaultTraceListener.

Of course, if another Trace Listener is wired up it might very well shadow all time spent in the DefaultTraceListener.

Approve answered 13/12, 2016 at 7:16 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.