We have a large database for the website back at work and also we have a high amount of disk IO and we were using the ASP.NET membership provider that comes built-in. We replaced the ASP.NET provider as it is not suited to a large scale application and has quite a lot of performance issues. For example it creates an anonymous user if you just hit the site ... which is true for even bots. Think of the amount of garbage user you can get with ASP.NET membership.
After deploying the performance improvement to the site we saw that the CPU usage to the site became 3 times higher than usual ... not much of an improvement ..eh! However from the changes made to the code it was obvious that there should not be higher CPU usage rather it should be low.
I downloaded a version of the DotTrace profile from Jetbrains. Its an amazing profiling tool. We have several web servers, I took one of the servers out of the load balancer. When you profile an ASP.NET app, the profile restarts the IIS. During that time we do not want the users to experience error or no page so its best to take the web server out of the load balancer. Turned on the profiler and then put the server back into the load balancer so that it can serve pages and encounters real life load. After a few minutes took a snapshot of the server. All this time CPU was high.
DotTrace is an amazing tool and it shows amount of time and the amount of calls and % for all methods and all methods called by your application.
Note: Some of the method names in the images are renamed or hidden for security and copyright reasons.
As one can see that the process request is taking 8.8% time which is normal but Application_AuthenticateRequest is taking 3.3% which is very strange.
Investigation showed that a method used to identify cookies from domain is taking huge time (see below). The code uses regular expressions.
Since our website calls itself internally from the server side from various requests generating a cookie for server side call should be wrong and this method validates if this is not a localhost call.
Then I investigated the code and found the following
private static bool IsValidDomainName(string inputString)
System.Text.RegularExpressions.Regex regex =
There are 2 things with this code. First of all this is a static function with a static expression validate with so the regex object can be static.
Second, the regex.IsMatch is a expensive function when it is in a area with high code coverage.
We just replaced this code with simple string matching and we our CPU just went down, see the web server CPU usage.
Click on the image to the high CPU usage vs after the applying the patch.
Dotrace can both CPU profile or memory profile an application and also have some cool views that you find bug fast.
It is evident that entry point of the request must me properly optimized as it called so many times. There is no chance for mistake for a code with huge coverage like that.