by

How to increase SharePoint performance. Use of retail and debug modes.

...when was the last time you checked your machine.config for retail="true" ?

I've heard a few times that SharePoint is a beast, a heavy monster, or is too slow, or is too boring. Truth is not many people out there are following SharePoint best practices. Just to mention one: when deploying a SharePoint solution many people overlook a simple switch that can make a huge difference and and have serious implications when we are talking about performance: The debug switch.
Maybe because it is too simple find in the web.config, maybe because it is too easy to change using notepad... the truth is: a lot of extra plumbing work is done when an application in debug mode is released to your users.
Scenario: we have a SharePoint page that has a delegate control. that delegate control loads a custom ascx that's deployed as a feature. that control might popup in many places across the whole portal.
 
What happens when your web.config has debug=false ?
For starters, let's take a look at the size of the generated assemblies, the number of handles created in the system and the internals of the asp.net DLL compilation.
When your SharePoint DLLs are compiled and deployed with the debug mode switch turned to false, the first thing you will notice is the assembly files. Look their sizes. They are determined by the compilation switch, not by the web.config switch. For comparison purposes I will use assemblies compiled in release mode against assemblies compiled in debug mode.
dll-web-config-debug-true-1

When your SharePoint web.config application has the web config debug = false SharePoint, or more precisely the .net framework, will handle the assembly reference this way:
 
sharepoint-performance-debug-false-web-config
When the user makes the very first request to a page that contains that ascx, the framework will compile that ascx into a temporary DLL. That DLL will receive a random name and it will not contain the code-behind that might be present in the GAC. The framework will also create a shadow copy of that DLL and both copies will be placed in the ASP.NET temporary folder. That reference will be returned to that page and the page will be rendered to the user.
sharepoint-batch-compilation-restart-iis-1
If you get to inspect the content of one of these files you will that that a kind of 'proxy' will be generated for them with all the references for the real control stored in the 12 hive. That's generated when the first call is made to the control.

contents of the file myapps.aspx.d7b311e5_CBMResult.compiled
<?xml version="1.0" encoding="utf-8"?>
<preserve resultType="7" virtualPath="/MySharepointApp.Personalisation.MyApps/12/TEMPLATE/LAYOUTS/MySharepointApp/MyApps.aspx"
          hash="fffffff6f2b2ee5f" filehash="fffffff6c7a1c8b7"
          flags="100000"
          CCUpreservationFileName="myapps.aspx.d7b311e5_CBMResult.ccu">
    <filedeps>
        <filedep name="/MySharepointApp.Personalisation.MyApps/_controltemplates/AudienceTrimmedControl.ascx" />
        <filedep name="/MySharepointApp.Personalisation.MyApps/_controltemplates/LinkSection.ascx" />
        <filedep name="/MySharepointApp.Personalisation.MyApps/_layouts/application.master" />
        <filedep name="/MySharepointApp.Personalisation.MyApps/12/TEMPLATE/LAYOUTS/MySharepointApp/MyApps.aspx" />
    </filedeps>
</preserve>
 
For all the subsequent requests from other pages using that same control, the same reference will be retrieved. It means the page will apply less pressure in the server and naturally the application will perform close to its best.
Now let's navigate the site opening more pages and see what's happening in the system. The number of handles keeps a steady balance.
sharepoint-memory-management-2
 
Now let's observe what happens if we do the same process and leave the web.config debug=true and we deploy the DLLs compiled in debug mode.
First thing we will notice is an increase in the assembly file, because the symbols added to the assembly.
dll-web-config-debug-true-2
It is not much of a difference, just 1-5 KB here and there.
so we are led to believe it will not increase the footprint on the system, right? Yeah.. but no...but yeah; that's not the problem, the problem will reveal itself when we inspect the page lifecycle...That's what's going to happen in this scenario.  
sharepoint-performance-debug-true-web-config 
For every single call to the page using the control, a brand new temporary DLL will be generated and that's my friend... is a problem. You can not afford to have a portal with, let's say, 500 pages and do not suffer from (the lack of) performance management  there with every single one of these assemblies loaded. See the overhead placed in the temp folder, see the overhead placed in the SharePoint portal handler...
Let's repeat the same process as case 1 and let's open another page that uses the same control. Look at the handlers in the system. They had a significantly increase. Now imagine that with hundreds of users.
 sharepoint-memory-management-1
That's going to be a lot of work for the garbage collector that should not be there if the person only took time to apply some basic best practices when deploying solutions. And the garbage collection is as we know a very expensive operation to be carried (probably) that often.

What should we do then?
Avoid debug=true in production environment. User Retail=true. Maybe you can't avoid people going there to the web.config and changing the settings to debug=true and false, but you can reduce the surface for problems. And one of the very first things you apply in production is the not so much talked about: retail mode.
    <system.web>
      <deployment retail="true" />
    </system.web>
The retail mode is a switch in the machine.config that automatically:
  1. ignores all the debug=true switches and force them to be false.
  2. disable the trace output in the pages
  3. disable the custom errors configuration
  4. disable the debug capabilities
In short: just flicking this switch you automatically reduces the surface for performance issues and also some hacking attacks by not exposing unnecessary information on the screen in case of an application crash. And because machine.config is hierarchically higher that web.config it will take precedence over any web.config from other applications deployed to your server.
Now go there and take a look how is your retail mode set and maybe with just a little flick you can change the performance of a whole portal and offer a better experience to the users.
See you later,

By