问题
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.
回答1:
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.
回答2:
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.
来源:https://stackoverflow.com/questions/15119791/performance-impact-of-defaulttracelistener