140
votes

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".

11
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
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
@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

11 Answers

105
votes

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.

64
votes

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.

12
votes

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.

6
votes

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.

3
votes

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.

3
votes

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.

2
votes

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.

2
votes

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.

1
votes

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.

1
votes

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.

0
votes

Turn off logging and debugging Make sure you deactivate logging and disable the debugging option before you build your application for release. You can deactivate logging by removing calls to Log methods in your source files. You can disable debugging by removing the android:debuggable attribute from the tag in your manifest file, or by setting the android:debuggable attribute to false in your manifest file. Also, remove any log files or static test files that were created in your project.

https://developer.android.com/studio/publish/preparing

How to remove all debug logging calls before building the release version of an Android app?

Difference between debug and release apks

Development, testing, acceptance and production

https://blog.chizobaogbonna.me/having-different-variants-debug-staging-release-of-your-app-on-a-single-device-2efdcaaf4950 https://ajiethkumar.wordpress.com/2017/04/07/it-environments-management/ enter image description here https://www.onlinecomputertips.com/support-categories/networking/646-what-is-a-dmz internal network vs perimeter

enter image description here enter image description here

https://dev.to/aws-builders/jump-over-a-hurdle-of-working-with-amplify-backend-environment-c77 enter image description here

https://en.wikipedia.org/wiki/Development,_testing,_acceptance_and_production https://oroinc.com/b2b-ecommerce/blog/testing-and-staging-environments-in-ecommerce-implementation/ enter image description here

https://medium.com/the-liberators/want-to-be-agile-drop-your-dtap-pipeline-7dcb496fe9e3 enter image description here

https://www.bmc.com/blogs/what-is-shift-left-shift-left-testing-explained/ enter image description here https://blogs.vmware.com/management/2013/11/features-for-thought-series-vcac-6-0-simplify-application-deployments-across-any-environment.html enter image description here https://enterprise.arcgis.com/en/server/10.3/administer/linux/arcgis-server-in-development-staging-and-production-environments.htm enter image description here https://learn.timextender.com/courses/259790/lectures/4029947 https://humanitec.com/blog/kubernetes-environments-basics https://blogs.oracle.com/openomics/leveraging-a-disaster-recovery-site-for-development-part-2 https://doc.oroinc.com/cloud/environments/ enter image description here

enter image description here enter image description here

enter image description here