148

I've encountered the following paragraph:

“Debug vs. Release setting in the IDE when you compile your code in Visual Studio makes almost no difference to performance… the generated code is almost the same. The C# compiler doesn’t really do any optimization. The C# compiler just spits out IL… and at the runtime it’s the JITer that does all the optimization. The JITer does have a Debug/Release mode and that makes a huge difference to performance. But that doesn’t key off whether you run the Debug or Release configuration of your project, that keys off whether a debugger is attached.”

The source is here and the podcast is here.

Can someone direct me to a Microsoft article that can actually prove this?

Googling "C# debug vs release performance" mostly returns results saying "Debug has a lot of performance hit", "release is optimized", and "don't deploy debug to production".

Raktim Biswas
  • 4,011
  • 5
  • 27
  • 32
sagie
  • 2,998
  • 3
  • 22
  • 31
  • possible duplicate of [Performance differences between debug and release builds](http://stackoverflow.com/questions/4043821/performance-differences-between-debug-and-release-builds) – Hans Passant Apr 01 '12 at 09:07
  • 1
    With .Net4 on Win7-x86, I have a CPU limited program that I wrote that runs nearly 2x faster in release than debug with no asserts/etc in the main loop. – Bengie May 14 '12 at 15:09
  • 1
    Also, if you care about memory use, there can be big differences. I've seen a case where a multi-threaded Windows service compiled in Debug mode used 700MB per thread, vs. 50MB per thread in the Release build. The Debug build quickly ran out of memory under typical usage conditions. – o. nate Apr 10 '14 at 13:51
  • @Bengie - did you verify that if you attach a debugger to the release build, it still runs 2x faster? Note that the quote above says that JIT optimization is affected by whether debugger is attached. – ToolmakerSteve Feb 26 '18 at 16:23

11 Answers11

112

Partially true. In debug mode, the compiler emits debug symbols for all variables and compiles the code as is. In release mode, some optimizations are included:

  • unused variables do not get compiled at all
  • some loop variables are taken out of the loop by the compiler if they are proven to be invariants
  • code written under #debug directive is not included, etc.

The rest is up to the JIT.

Full list of optimizations here courtesy of Eric Lippert.

Pang
  • 9,564
  • 146
  • 81
  • 122
Adrian Zanescu
  • 7,907
  • 6
  • 35
  • 53
  • 10
    And don't forget about Debug.Asserts! In DEBUG build, if they fail, they will halt the thread and pop up a message box. In release they get not compiled at all. This applies for all methods that have [ConditionalAttribute]. – Ivan Zlatanov Mar 15 '10 at 09:35
  • 13
    The C# compiler does not do tail call optimizations; the jitter does. If you want an accurate list of what the C# compiler does when the optimize switch is on, see http://blogs.msdn.com/ericlippert/archive/2009/06/11/what-does-the-optimize-switch-do.aspx – Eric Lippert Mar 15 '10 at 13:54
69

There is no article which "proves" anything about a performance question. The way to prove an assertion about the performance impact of a change is to try it both ways and test it under realistic-but-controlled conditions.

You're asking a question about performance, so clearly you care about performance. If you care about performance then the right thing to do is to set some performance goals and then write yourself a test suite which tracks your progress against those goals. Once you have a such a test suite you can then easily use it to test for yourself the truth or falsity of statements like "the debug build is slower".

And furthermore, you'll be able to get meaningful results. "Slower" is meaningless because it is not clear whether it's one microsecond slower or twenty minutes slower. "10% slower under realistic conditions" is more meaningful.

Spend the time you would have spent researching this question online on building a device which answers the question. You'll get far more accurate results that way. Anything you read online is just a guess about what might happen. Reason from facts you gathered yourself, not from other people's guesses about how your program might behave.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
  • 3
    I think you can care about performance yet still have a desire to use "debug". For example, if most of your time is waiting on dependencies, I don't think building in debug mode will make a big difference, yet you have the added benefit of getting line numbers in stack traces, which may help fix bugs faster and make happier users. The point is you have to weigh the pros and cons, and a general "running in debug is slower, but only if you're CPU bound" statement is enough to help with the decision. – Josh Mouch Dec 18 '18 at 16:05
13

I can’t comment on the performance but the advice “don’t deploy debug to production” still holds simply because debug code usually does quite a few things differently in large products. For one thing, you might have debug switches active and for another there will probably be additional redundant sanity checks and debug outputs that don’t belong in production code.

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
6

From msdn social

It is not well documented, here's what I know. The compiler emits an instance of the System.Diagnostics.DebuggableAttribute. In the debug version, the IsJitOptimizerEnabled property is True, in the release version it is False. You can see this attribute in the assembly manifest with ildasm.exe

The JIT compiler uses this attribute to disable optimizations that would make debugging difficult. The ones that move code around like loop-invariant hoisting. In selected cases, this can make a big difference in performance. Not usually though.

Mapping breakpoints to execution addresses is the job of the debugger. It uses the .pdb file and info generated by the JIT compiler that provides the IL instruction to code address mapping. If you would write your own debugger, you'd use ICorDebugCode::GetILToNativeMapping().

Basically debug deployment will be slower since the JIT compiler optimizations are disabled.

Neil
  • 1,912
  • 17
  • 24
4

What you read is quite valid. Release is usually more lean due to JIT optimization, not including debug code (#IF DEBUG or [Conditional("DEBUG")]), minimal debug symbol loading and often not being considered is smaller assembly which will reduce loading time. Performance different is more obvious when running the code in VS because of more extensive PDB and symbols that are loaded, but if you run it independently, the performance differences may be less apparent. Certain code will optimize better than other and it is using the same optimizing heuristics just like in other languages.

Scott has a good explanation on inline method optimization here

See this article that give a brief explanation why it is different in ASP.NET environment for debug and release setting.

Fadrian Sudaman
  • 6,405
  • 21
  • 29
3

In msdn site...

Release vs. Debug configurations

While you are still working on your project, you will typically build your application by using the debug configuration, because this configuration enables you to view the value of variables and control execution in the debugger. You can also create and test builds in the release configuration to ensure that you have not introduced any bugs that only manifest on one type of build or the other. In .NET Framework programming, such bugs are very rare, but they can occur.

When you are ready to distribute your application to end users, create a release build, which will be much smaller and will usually have much better performance than the corresponding debug configuration. You can set the build configuration in the Build pane of the Project Designer, or in the Build toolbar. For more information, see Build Configurations.

hallie
  • 2,760
  • 19
  • 27
3

One thing you should note, regarding performance and whether the debugger is attached or not, something that took us by surprise.

We had a piece of code, involving many tight loops, that seemed to take forever to debug, yet ran quite well on its own. In other words, no customers or clients where experiencing problems, but when we were debugging it seemed to run like molasses.

The culprit was a Debug.WriteLine in one of the tight loops, which spit out thousands of log messages, left from a debug session a while back. It seems that when the debugger is attached and listens to such output, there's overhead involved that slows down the program. For this particular code, it was on the order of 0.2-0.3 seconds runtime on its own, and 30+ seconds when the debugger was attached.

Simple solution though, just remove the debug messages that was no longer needed.

Lasse V. Karlsen
  • 380,855
  • 102
  • 628
  • 825
3

I recently run into a performance issue. The products full list was taking too much time, about 80 seconds. I tuned the DB, improved the queries and there wasn't any difference. I decided to create a TestProject and I found out that the same process was executed in 4 seconds. Then I realized the project was in Debug mode and the test project was in Release mode. I switched the main project to Release mode and the products full list only took 4 seconds to display all the results.

Summary: Debug mode is far more slower than run mode as it keeps debugging information. You should always deploy in Relase mode. You can still have debugging information if you include .PDB files. That way you can log errors with line numbers, for example.

Francisco Goldenstein
  • 13,299
  • 7
  • 58
  • 74
1

To a large extent, that depends on whether your app is compute-bound, and it is not always easy to tell, as in Lasse's example. If I've got the slightest question about what it's doing, I pause it a few times and examine the stack. If there's something extra going on that I didn't really need, that spots it immediately.

Mike Dunlavey
  • 40,059
  • 14
  • 91
  • 135
1

Debug and Release modes have differences. There is a tool Fuzzlyn: it is a fuzzer which utilizes Roslyn to generate random C# programs. It runs these programs on .NET core and ensures that they give the same results when compiled in debug and release mode.

With this tool it was found and reported a lot of bugs.

Sergey Ponomarev
  • 2,947
  • 1
  • 33
  • 43
0

I just explain my own experience.

I work in health industry on several enterprise level applications. We did measure the performance of Debug VS Release (VS 2019 .NET 4.7) Majority of our applications are Web forms and C# based.

The difference between debug and release for various functions and pages in our case was only about a second(in fact less than 1 second.)

Now our business really do not care about this difference, but If I was handling an application for handling Market Stock transactions then even milliseconds were important and that exactly where Release mode becomes important.

S Nash
  • 2,363
  • 3
  • 34
  • 64