Surprising performance problem under debugger
Using NET 8.0 and Visual Studio 2022 Enterprise.
I've written an application that reads large XML files, does some processing on them, and then inserts records into SQL Server.
It works great, except it's slow. It executes 400 to 500 batches per second when I run it. That stinks!
To try to figure out what was wrong, I ran it under the profile (Debug > Performance Profiler). I turned on EWT and sampling, and I was off to the races.
I was very surprised that it ran at its expected speed! It can clear more than 35,000 batches per second, peaking at over 45,000/sec sometimes. What the heck? I didn't notice anything in the profile: SQL is the slowest, and I expect that. My parsing and processing does some work, but it's still faster than reading the input file.
So I tried running the app directly from the command line, without the debugger. Turns out it runs at very fast there, too. What gives? I'd expect some performance impact from the debugger, but not much -- and certainly not 100 times slower. And so I spent a lot of time assuming I had done something wrong: connection pool not working, locking where I thought I wasn't, getting single-threaded when I should've have been concurrent, ... ? Turns out it was the debugger the whole time.
What gives? Is this just a fact, or is there some setting I can diddle that will make app performance under the debugger more realistic? What is it that the debugger is doing to the process that's making it so awful?
5 Replies
Yeah that's normal
It probably turns off most of the jitting and that's why
If you have conditional breakpoints it's going to be even slowrt
No conditional breakpoints. So without JIT it's just running IL?
I've never noticed it being so slow before.
I don't know
Maybe there still remains some level of optimization, I have never looked into that
Anything I read says that IL is never executed directly, so there's still some compilation going on.
Back in managed code, it was trivial to open the "View Disassembly" window i nthe debuger to see what code was being actually executed when debugging C or C++ apps.
I thought that could be done with C# apps too, to see the IL. But I can't get it to happen.
If the code in the debugger is 20 or 30% slower, that seems fine. But 100x slower is just terrible, and very unexpected.
if the application is highly threaded or async, then the slowdown seems expected (https://github.com/dotnet/runtime/issues/38736) it should be fixed in .NET 9
GitHub
Debugger.NotifyOfCrossThreadDependency can be slow when a debugger ...
Description Certain code paths will call Debugger.NotifyOfCrossThreadDependency. NotifyOfCrossThreadDependency is pretty close to free when there is no debugger attached, so if you are in a situati...