|
Optimize ASP.NET Performance (Continued)
This might seem like a natural place to discuss ASP.NET 2.0's ability to discard cached data automatically if the data in the database changes. However, it remains unclear whether this feature will improve your performance if you don't also use SQL Server 2005. With the current versions of SQL Server, enabling dependencies between SQL Server and ASP.NET requires ASP.NET to check back with SQL Server on some schedule to see if data has changed. This extra work could degrade your performance more than caching helps it.
Caching also demonstrates what I said at the start of the article: Performance is often a trade-off between speed and memory. Faster processing often comes at the cost of using more memory or at the cost of changing your application's behavior.
The SqlDataSource object's DataSourceMode in ASP.NET 2.0 provides another demonstration of this rule. Setting the SqlDataSource's DataSourceMode to DataReader gives you the least memory consumption and fastest processing when retrieving data. However, controls bound to a SqlDataSource can lose some functionality when DataSourceMode is set to DataReader (the DataGrid won't be able to sort or filter data). Setting DataSourceMode to DataSet gives you that functionality, but at the cost of having the SQLDataSource take up more room in memory and take a little longer to retrieve your data. You might have to experiment to find what gives your site the best results.
Watch for Errors and COM
Things can go wrong, and you should provide error handling to catch those problems. But don't use error handling to take care of conditions that you can check for (unless those conditions are extremely rare). Exception handling is expensive in ASP.NET. You get better performance by checking for a condition and not raising the error than you do by putting the code in a Try block and hoping the condition doesn't exist. In other words, check whether your divisor is not equal to zero before dividing—don't attempt the division in a Try block.
If your application started life as an ASP page with VBScript, then you implemented your error handling using On Error Resume statements. ASP.NET supports using On Error Resume for Visual Basic—but it's extremely slow. Replace your On Error Resume statements with Try blocks.
If you call a COM object from your ASP.NET page, you need to do more than set your variables to nothing to release your COM objects. Setting a variable to nothing only makes the wrapper that .NET puts around your COM object available for garbage collection. It can be a long time before your wrapper gets garbage collected, and your COM object hangs around in memory until that happens. Use the ReleaseComObject method of the System.Runtime.InteropServices.Marshal object when you finish with an object, passing the reference to your COM object to release it. Your .NET wrapper still must wait for the garbage collector to collect it before you can get back the memory held by your COM object.
Unfortunately, there is a catch when using ReleaseComObject: Under some circumstances, you must call the method more than once. In fact, you must keep calling ReleaseComObject until the method returns 0 to ensure that your COM object is released. This code does the trick:
Dim ComObject As SomeCOMObject
Do Until System.Runtime.InteropServices. _
Marshal.ReleaseComObject(ComObject) = 0
Loop
ASP.NET 2.0 provides a simpler solution: Call the Marshal object's FinalReleaseComObject method, passing your object like this:
System.Runtime.InteropServices.Marshal. _
FinalReleaseComObject(ComObject)
Another important performance principle is to make sure that you get the fastest (and fewest) compiles. In ASP.NET 1.0, you should change your application's Configuration setting before you release it. Simply select Build | Configuration Manager and change your application's Configuration setting to Release. This gives you a more optimized build and skips generating any debug support.
Note that your application's code is never fully compiled when it leaves Visual Studio—at best, .NET converts your code to IL code, but the code must be compiled to native code after you install the application on the server. In ASP.NET 1.1, this final compilation happens the first time that a page is requested from the site. You shouldn't make your users wait for your site to compile; instead, you should force compilation by requesting a page from the site yourself.
The situation is compounded in ASP.NET 2.0 where two of the deployment methods (copying the Web site and creating a setup package) don't even compile your source code to IL. Only Build | Publish Web Site generates IL code. You can force compilation for your Web site by calling the precompile.axd utility after installing your application (the utility ships with .NET 2.0). All you need to do is append the utility's name to the end of your site's URL, like this: http://MyServer/MySite/precompile.axd.
I hope these tips prove useful to you. The usual disclaimer applies: Results are dependent on the application, and your mileage may vary. In any case, trying out some of these changes and monitoring your site's performance will give you the best insights for what works on your site. In addition, ASP.NET 2.0 will have different performance characteristics than ASP.NET 1.1. Remain up to date by constantly searching the MSDN site as well as Visual Studio Magazine's Web site for new articles with the keywords "ASP.NET" and "performance." Like life, performance is a journey, not a destination.
About the Author
Peter Vogel (MBA, MCSD) is a principal at PH&V Information Services. Peter teaches for Learning Tree International and wrote its ASP.NET and Technical Writing courses. Peter is the editor of the Smart Access newsletter from Pinnacle Publishing and wrote Visual Basic Object & Component Handbook (Prentice Hall). He is currently working on Professional Custom Controls, Web Parts, and User Controls with ASP.NET 2.0 for Wrox.
Back to top
|