Rider Performance Penalty?

Answered

I'm noticing a performance penalty when I start my process in Rider using a Debug run configuration vs `dotnet run -c Development`. Is this something I should expect, or should they be virtually indistinguishable? The performance dip I'm seeing is about 20% on this particular application, which is an I/O intensive application that mostly copies data from one database to another. I'm on Mac w/ Catalina, using the Rider 2019.3. Obviously I could do a lot more investigation, and I'm happy too, but before spending a lot of time on this I'm curious what I should expect.

I'm relatively new to Dotnet. My experience with Java tells me I shouldn't be seeing this much of a performance change. But I wanted to check with others that might know before I begin the process of tearing my hair out to figure out why it's slower. Thanks!

-Andrew

5 comments
Comment actions Permalink

One more comment. I don't have any breakpoints set, and in particular I have no breakpoints with conditional expressions. (In Java these could really slow things down.)

0
Comment actions Permalink

Would exceptions being thrown have a bigger impact on performance hit in Debug than Run? I noticed the performance hit for Debug is worse when the running code throws more exceptions.

0
Comment actions Permalink

Indeed throwing exceptions, even if they are caught and handled, is much, much, more expensive in Debug mode. The program below takes 0.024s to run in Run, and 52s to run in Debug. So you could say is 2,000x slower... but I wouldn't draw too much of a conclusion from such a contrived example.

That said, I think code that relies on exception handling for control flow during string parsing can suffer when there are lots of bad string values. Which is exactly what's going on in my use case, and why the code slows down so much when running in Debug mode.

Why it's so much slower might be something Rider devs want to look at...

 

namespace Main
{
class Program
{
static void Main(string[] args)
{
Stopwatch w = Stopwatch.StartNew();
for (int i = 0; i < 1000; ++i)
{
try
{
throw new InvalidCastException();
}
catch { }
}
Console.WriteLine(w.ElapsedMilliseconds / 1000.0f);
}
}
}
0
Comment actions Permalink

Hello Andrew,

The workflow is this case is as follows: runtime fires an event that the exception was thrown. Debugger listening to these events. If it notices such event, then it stops the process, gets the event and decides if the process should resume. This procedure takes time, especially on .NET Core comparing to full framework. This means that the performance penalty during debugging, when exceptions are thrown, is expected, this is how debugger on .NET Core works. 

0
Comment actions Permalink

Hi Olga,

Thanks for the follow up. Makes sense. I suspected it might be something like this. Perhaps .NET 5 will give us more performant options.

0

Please sign in to leave a comment.