Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I avoid slow .net exceptions in DEBUG with the debugger attached?

Can I run a program that heavily uses exceptions in the debugger and not catch the exceptions in the debugger?

Specifically I'm trying to use the TSQL ScriptDOM parser, and I understand that it's use of ANTLR is slow in debug mode.

It is not that strange if you look at the debug output, you will find that this is caused by the Microsoft® SQL Server® 2012 Transact-SQL ScriptDom parser, since this is based on the ANTLR framework, it unrolls AST productions using exceptions, this is what it makes it slow when running inside the debugger.

I completely understand that .net exceptions are slow when thrown

How can I avoid the slowness when running with the standard DEBUG configuration, with the debugger attached?

  • I've disabled intellitrace.
  • I've undefined the DEBUG constant.
  • I've turned off exception messages in the Tools > Options > Debugging > Output Window.

What else can I try?

  • a CLR setting I can change via the app.config?
  • an option to change in Visual Studio?

This is the specific code I am using for parsing.

TSqlParser parser = new TSql110Parser(false);
IList<ParseError> errors;
TSqlFragment fragment = parser.Parse(new StringReader(sqltext), out errors);

When run using CTRL+F5 it finishes quickly, and using F5 (debugger attached), I give up waiting.

like image 323
JJS Avatar asked Oct 28 '15 15:10

JJS


People also ask

Is Debug slower than run?

Unfortunately, debugger speed has some runtime limitations, which can't be easily fixed. If your code does some high performance computations, Debugger will be at least 3 times slower than usual Run.

Is debug mode slower Visual Studio?

Visual Studio is typically painfully slow to debug or just plain load ("start without debugging") my ASP.NET MVC sites. Not always: at first, the projects will load nice and fast, but once they load slow, they'll always load slowly after that.


2 Answers

If you have some code which throws a lot of exceptions, it can perform very slowly if the debugger is attached.

To improve the speed of such a method, you can add the DebuggerNonUserCode attribute to the top. For example:

[DebuggerNonUserCode]
public static bool IsArchive(string filename)
{
    bool result = false;
    try
    {
        //this calls an external library, which throws an exception if the file is not an archive
        result = ExternalLibrary.IsArchive(filename);
    }
    catch
    {

    }
    return result;
}
like image 143
Fidel Avatar answered Oct 22 '22 21:10

Fidel


One possible workaround you can do (I ran in to a similar issue where a image processing library would throw a OutOfMemoryException if used while the debugger was attached on a particularly large dataset) is put a breakpoint before calling in to the 3rd party library code and detaching the debugger, after the breakpoint re-attach the debugger with a Debugger.Launch().

#if DEBUG
bool debuggerAttached = Debugger.IsAttached;
if(debuggerAttached)
{
    Debugger.Break(); //Detach the debugger to make the next section faster.
}
#endif

TSqlParser parser = new TSql110Parser(false);
IList<ParseError> errors;
TSqlFragment fragment = parser.Parse(new StringReader(sqltext), out errors);

#if DEBUG
if(debuggerAttached && !Debugger.IsAttached)
{
    Debugger.Launch();
}
#endif
like image 34
Scott Chamberlain Avatar answered Oct 22 '22 23:10

Scott Chamberlain