tags:

views:

105

answers:

3

Pretty much what the title says: I'm running a long program, and it has the CLR debugger attached, so I can catch and inspect exceptions. Am I getting performance comparable to running it without the debugger, or is there a serious (2-10x or more) penalty I'm paying?

+2  A: 

Attaching the debugger disables some JIT optimizations -- for example function inlining.

http://msdn.microsoft.com/en-us/library/bb384548.aspx

Your performance may be worse.

Laurion Burchall
Also keep in mind that you have to compile the code in debug mode in order to attach the debugger, so depending on your programming style you might have a lot of debug code that gets optimized out when you compile in release mode.
StriplingWarrior
@StriplingWarrior by no means is it required you compile something in debug mode to attach the debugger.
Logan Capaldo
Interesting. You learn something new every day. Thanks for the correction.
StriplingWarrior
+4  A: 

I've seen pretty substantial differences, yes.

In particular, when exceptions are thrown they take a lot longer when the debugger is attached. There are some other significant optimizations which can affect behaviour - for example, the garbage collector is much more aggressive when the debugger isn't attached.

Why not just log the exceptions instead of breaking into the debugger? Apart from anything else, that means if you want to go back and look at an exception which happened yesterday and compare it with one which has happened just now, that's easy... it's harder to travel back in time :)

Jon Skeet
Debugging especially seems to take longer for me when I'm debugging an ASP.NET program from a non-IE browser.
StriplingWarrior
+2  A: 

The biggie: Tools + Options, Debugging, General, Supress JIT optimization on module load. You want that off if you want to debug release code and get comparable perf. That does however make it harder to debug your code, the JIT optimizer will store local variables in CPU registers (Watch won't work) and reorder and inline code (stepping acts weird).

Then there's the DebuggableAttribute, automatically generated by the compiler. Its IsJITOptimizerEnabled and IsJITTrackingEnabled properties matter. For one, they work to keep local variables alive just a wee bit longer than necessary, preventing the garbage collector from collecting references that you might want to inspect in the debugger. Easy to avoid, just debug the Release build instead of the Debug build.

Then there is specific stuff that happens in your program that wakes up the debugger and make it steal CPU cycles:

  • when your program throws an exception. The debugger gets a shot at it before it is thrown. Called a "first chance notification", you see it in the Output window. That's what makes the Debug + Exceptions dialog work. Slows down the exception processing a lot.
  • when your program loads or unloads a DLL. Lots of stuff happens at load time, the debugger tries to find symbols for the DLL. Checks if any breakpoints need to be activated. And displays a notification in the Output window. This typically only makes the startup of your program slow, especially when you've got mixed-mode debugging turned on.
  • when you use the Trace class with the DefaultTraceListener, Debug.Write/Line() method or Console.Write/Line with the hosting process enabled. The output appears in the Output window, slows down these calls a lot.
  • when a thread in your program is started or stops. Visible in the Output window. Getting this to slow down your program would be a design mistake.

That's about it, the debugger stays out of the way and lets your code run at full speed as long as it doesn't do what's listed above. Runtime environments like ASP.NET and Silverlight are special and probably have additional overhead. So does debugging an Any CPU program on a 64-bit operating system, that requires the remote debugger because VS is 32-bit only.

Hans Passant