DotNetNuke is a large ASP.NET CMS which is mostly pre-compiled, as are most of the modules contained within.
When we deploy our DotNetNuke site changes, we have two bits of recompilation that occur upon the first page hit.
- Application-level recompilation that occurs when a DLL is replaced in the bin folder
- Each time an individual module is accessed for the first time, some recompiling occurs on that specific module.
Is there a way to allocate more of the CPU capacity to compiling asp.net sites in IIS 7?
- I'd like to use more than one core, or at least do something to reduce recompile time.
Q&A
You should use pre-compiled ASP.NET. Why aren't you?
- We are using pre-compiled ASP.NET. Just because an ASP.NET app is compiled into a DLL does not mean that the ASP.NET runtime will not do additional recompiling in order to serve it to vistiors.
How do you know it's recompiling and not populating the cache or something?
- Viewing the task manager on the server shows 50% CPU usage by the compiler executable during the aforementioned page hits. Why 50%? 2-core server.
Set <compilation optimizeCompilations="true" />
Specifies whether dynamic compilation will recompile an entire site if a top-level file is changed. Top-level files include the Global.asax file and all files in the Bin and App_Code folders. If True, only changed files are recompiled.
Source: compilation Element (ASP.NET Settings Schema)
More information about the pros and cons can be found at Understanding ASP.NET Dynamic Compilation, under Optimizing Dynamic Compilation. The primary cause of errors are removal or changes in existing method signatures, causing already compiled pages to throw a MissingMethodException until they are recompiled.
You could also look into reducing the batch size for batch compilation, or disable it completely. I believe this will reduce compilation times for single pages, but generate more assemblies and consume more memory.
I have had this exact same experience with DotNetNuke in the past. Our issue was that we had about 125-150 modules installed, all with their own assemblies. The sheer number of them would cause the first request delay to be close to a minute or more. It was worse during deployment time as we would purposefully re-install our own custom modules. Later, we adjusted the deployment scripts to avoid installing modules already installed, and this helped. However, the first request was still a bear because it was running both the VB.NET and C# compiler (our modules were C# while DNN was VB.NET at the time).
While we used the optimizeCompiliations
attribute to help a bit, you also need to consider ensuring there isn't a real-time virus scanner monitoring both the directory where the code is and the Temporary ASP.NET Files folder. This will slow the compilation to a crawl.
Next, you may be able to consider using ILMerge to merge some assemblies into a single assembly, but I know that we avoided this option as it caused us more deployment headaches than it was going to solve.
Lastly, this is a scenario where some additional hardware isn't a bad idea. What will help the most is a faster CPU just to get the compilation time down to a reasonable amount of time.
DotNetNuke.com has a few performance tuning hints in their Wiki. The one that helped the most with performance in general was truncating the EventLog and SiteLog tables as they can get very large if you don't pay attention to them. There's a table or two involved in the site indexing as well that, in some versions, grew out of control. Honestly, this isn't your issue. You are having the typical ASP.NET cold-start issue.
There are also some common ASP.NET performance issues you may want to look into as well. This one talks about both cold and warm-start performance enhancements.
I'm pretty sure it's not possible since the compilation is performed within a single thread, which can't span processors. Running the site spans processors/cores, but the first hit compile does not.
What you can look at is breaking your solution into projects. Then a smaller portion of your site needs a full recompile.
Is precompilation instead of dynamic compilation an option ?
50% of CPU utilization on a 2 core CPU system indicates that the ASP.NET compiler is single threaded. You would have seen a 25% CPU utilization on a quad core system.
To the best of my knowledge, there is no magic way of turning it to a multi-threaded compiler.
One thing you could do however, is to use the ASP.NET compilation tool to pre-compile the whole site before deploying it. Do this on a dev/staging box and deploy to prod, and your prod deployment shouldn't be suffering from these delays.
Must bite my tongue, but I have to ask; do you really deploy to prod that often that this is a problem?