Migrating from ASP 3.0 to ASP.NET with Performance in mind

 

Author: Ing. Pieter R. Siegers

Date: Jan. 2003

 

Migrating from ASP 3.0 to ASP.NET with Performance in mind. 1

Introduction. 1

Typical performance of an (optimised) ASP 3.0 application. 3

Fig. 1 Screenshot Optimised Web Application ASP 3.0. 4

Fig. 2 Report ACT ASP 3.0 Web Application. 7

Fig. 3 Report ACT for ASP.NET Web Application. 10

Fig. 4 Combined ACT report on Classic ASP 3.0 & ASP.NET Web Application. 10

Fig. 5 ACT report after first analyse step. 12

Fig. 6 ACT report after second analyse step. 13

Fig. 7 ACT report after third analyse step. 14

Things to improve on the ASP.NET application. 14

Fig. 8 Performance tests and results after first improvement step. 15

Fig. 9 Performance tests and results after second improvement step. 17

Fig. 10 Performance tests and results after third (and final) improvement step. 18

Fig. 11 Final application performance comparison. 19

Conclusion. 19

 

Introduction

 

 

A while ago, I was asked to make a performance comparison between ASP 3.0 and ASP.NET. Wow, I thought, this is my chance of proving that ASP.NET could easily win that battle – well boy, was I wrong! I found that simple and straight .NET development could not win that battle, and that more specific program features were needed to make .NET a winner.

 

So, with that in mind, I wrote this article. I think it is a well worth subject to look closer at. Thus, the main purpose of this article is to discuss migrating to ASP.NET of existing ASP 3.0 (Web) Applications (often referred to as “Classic ASP” now) with application performance in mind. To be clear on the subject, I will only look into performance, an important part of Load-Testing. Other parts of this broad subject are scalability and durability, both interesting subjects but, as said, not in scope here.

 

I will simply use an existing but simple ASP 3.0 web application, which will be optimised using the latest tips & tricks available for optimising and speeding up the code. It will naturally make use of COM, XML, and XSLT to get data and present it to the users. Javascript will be used to glue everything together.

 

Performance and simplicity are the most important factors in the design of this implementation – it does not contain any real sophisticated error handling, although basic “try-catch-finally” constructs are used whenever there may be a need for it.

 

Next, the application will be subject to a simple performance test using one machine as the Web Server, another one as the Database Server, and a third one as our stand-alone performance tester with Microsoft Application Center Test (ACT) installed. ACT comes with the VS.NET package – more on this later. This will give us a justified overview of how our application performs at different tiers, although in this article the focus will be on the Web Server and how quick it is able to display the data being requested.

 

Then, our classic application will be migrated to ASP.NET, with exactly the same functionality – but of course not using Interop Services (COM) which could make its overall performance worse – no, only using 100% ASP.NET. Then, the ported application was also subject to the same performance tests as with the Classic ASP approach, and like I already said, it turned out that the classic approach was substantially faster and also more stable then the ASP.NET implementation… really? YES, it was!! I can tell you, that really was a surprise to me!

 

OK, if this was the case then why everybody (well, mostly MS and its partners) is claiming ASP.NET out-of-the-box technology is just faster then ASP 3.0 then? I admit that it always depends greatly on the actual case of course; each Web Application is different and requires a different approach. Still, I decided to report back with the real results – boy, that surprised everyone involved in the project! They all (naturally) also expected to hear that ASP.NET was the winner! I knew I was faced with a problem I had just created myself, you know, being a pro ASP.NET guy – but what could I do about it?

 

So, after a while thinking about what really was happening behind the curtains, I thought, OK, the classic application is an optimised one, so this particular case allows me to make the same kind of optimisations to the ASP.NET application that were done for the classic ASP 3.0 application, but this time using new ASP.NET technology features, and see what happens.

 

I did just that. Using Microsoft Application Center Test (ACT), I first analysed and changed the actual application bit-by-bit, and yes, as a result, the performance of ASP.NET was finally getting better than the classic approach. This sure was a relief – let me tell you, I had been promoting ASP.NET in my company since I attended the Microsoft PDC back in 2000, when the .NET Framework was officially released, together with VS.NET!

 

Conclusion? You may well be subject to the same circumstances as I found my self about a few months ago. It seems that these days very few people concern themselves with how well an application performs when transitioning from one well-established technology like ASP 3.0 was (and still is without doubt), to a brand new one. But lighten up – read on and I will show you how to make ASP.NET a winner.

 

 

Typical performance of an (optimised) ASP 3.0 application

 

Back in the days of Classic ASP, developers and investigators gathered a list of tips & tricks as time went by, fed by those who discovered shortcomings and solutions to problems inherent to the ASP programming model. This now well-known list was extended as time went by, by enhancing the ability to use COM objects, as well on the server side as on the client side. IIS evolved during this period, solving some problems on that same list, others not because they related to deeper levels of the operating system. It never could solve the DLL Hell problem, to give an example. I still have this list ready for use in several documents, each one delving into a specific subject.

 

On the other hand, for ASP.NET there still isn't an extensive list yet, although some things are already widely known of course. There are some articles on this subject, but they are few, and not very objective neither very useful.

 

So I thought, I would need a simple but optimised web application to be able to compare with a similar web application built with ASP.NET. And from these experiences, I could start to make a brand new list of tips & tricks for optimising ASP.NET performance.

 

The Web Application I built looks like the following screenshot shows. It simply shows the results of a database query in a table form:

 

 

Fig. 1 Screenshot Optimised Web Application ASP 3.0

 

This Web Application has one page that takes care of accessing the database using SQLXML and getting the data as XML, then performing an XSLT using MSXML and a XSL Stylesheet.

 

The code for this page (Default.asp in folder "ASPClassic2dotNETASP30") is shown below:

 

<%@ language="JavaScript" %>

 

<HTML>

<HEAD>

      <title>ASP 3.0 classic</title>

</HEAD>

<BODY bgcolor="#66ff99">

 

<%

 

function GetXML(strMethod,strURL,strAsync,strUserId,strPassword)

{

      try

      {

            // initialize an http request

            // and pass the URL and credentials

      srcDoc.open(strMethod,strURL,strAsync,strUserId, _

                        strPassword);

            // send the http request (get the page)

            srcDoc.send();

            // return the result

            return srcDoc.responseXML;

      }

      catch (e)

      {

            Response.Write("Error occurred while trying to load _

              the XML Source.<br>" + "Error Description: " + _

              e.description);

            Response.End;

      }

}

 

function getProcessorApp(XslStylesheetName)

{

      xslProcessor = Application(XslStylesheetName).createProcessor();

      return xslProcessor;

}

 

function transformDataS(srcDoc,xslProc)

{

      xslProc.input = srcDoc;

      xslProc.transform();

      Response.Write(xslProc.output);

      return true;

}

 

var srcDoc = Server.CreateObject("MSXML2.ServerXMLHTTP.4.0");

var strMethod = "GET";

var strURL = "http://localhost/aspclassic2dotnet_sqlxml/templates/customers.xml";

var strAsync = "False";

var strUserId = "";

var strPassword = "";

srcDoc = GetXML(strMethod,strURL,strAsync,strUserId,strPassword);

var xslProc = getProcessorApp("xslDoc");

 

transformDataS(srcDoc,xslProc);

%>

 

</BODY>

</HTML>

 

The code starts with the following lines, where initialisation of objects take place, and where variables are being assigned a value:

 

var srcDoc = Server.CreateObject("MSXML2.ServerXMLHTTP.4.0");

var strMethod = "GET";

var strURL = "http://localhost/aspclassic2dotnet_sqlxml/templates/customers.xml";

var strAsync = "False";

var strUserId = "";

var strPassword = "";

 

Then, the XML data is retrieved from the database:

 

srcDoc = GetXML(strMethod,strURL,strAsync,strUserId,strPassword);

 

Here, the first function is called, GetXML(), which takes five parameters: the HTTP Request Method, the URL, an Asynchronous flag, a User ID/login, and finally a Password. The function GetXML() executes the following code:

 

      try

      {

      srcDoc.open(strMethod,strURL,strAsync,strUserId, _

                        strPassword);

            srcDoc.send();

            return srcDoc.responseXML;

      }

      catch (e)

      {

            Response.Write("Error occurred while trying to load _

              the XML Source.<br>" + "Error Description: " + _

              e.description);

            Response.End;

      }

 

Within the try-catch construct, the source document object 'srcDoc' is filled with the output of the result of the query that is executed against SQL Server when the contents of the SQL Query Template is read and executed. This actually happens on this line:

 

            srcDoc.send();

 

Then, the result is returned:

 

            return srcDoc.responseXML;

 

If an error occurs, the catch will write out the error information and end the page response.

 

Suppose the XML source is correctly returned, then the code continues here:

 

var xslProc = getProcessorApp("xslDoc");

 

Here, another function is called, getProcessorApp(), which takes only one parameter, XslStylesheetName, which is the name of the stylesheet application variable:

 

      xslProcessor = Application(XslStylesheetName).createProcessor();

      return xslProcessor;

 

This effectively gets the cached XSL Stylesheet which was created in the Global.asa file (see below for code) and creates the XSL Processor. It is then returned as an object to the caller.

 

The Global.asa contains the code for the XSL Stylesheet Application variable:

 

Xxx – code global.asa

 

At last, the final function is called to apply the XSLT, and write the resulting output to the Response Output Stream:

 

transformDataS(srcDoc,xslProc);

 

The function transformDataS() takes 2 parameters, srcDoc and xslProc, which resp. are the XML Source Document, and the XSL Processor containing the XSL Stylesheet. The code is as follows:

 

      xslProc.input = srcDoc;

      xslProc.transform();

      Response.Write(xslProc.output);

      return true;

 

This code first assigns the input to the XML Source, it then transforms the XML using the XSL Stylesheet (in other words, an XSLT is performed), and then writes out the resulting output to the client before returning control to the caller.

 

Note that in the last two functions I didn't make use of try-catch blocks – which obviously would have been better to do, but here it was omitted because of readability. Actually, normally the code would be more extensive because of added error-handling code which makes it rather unreadable.

 

 

The performance of this Web Application was measured using Application Center Test (ACT), which comes with VS.NET Enterprise Architect. ACT is a follow-up of the former performance tool, the Web Application Stress Tool (WAST). They are very similar but the latter comes both as a plug-in for VS.NET and as a stand-alone program, and both have some improvements over the old WAST tool. Currently, the stand-alone program has more functionality than the plug-in, so I decided to go with the stand-alone version. Using ACT, you can create very easily compact and useful reports, both graphical and textual.

 

Below are some results of using ACT to load-test the above-mentioned Web Application. It shows clearly that when the amount of concurrent connections rise, the maximum throughput (measured in RPS, or Requests Per Minute – interpreted as the higher the better) of the Web Server proportionally decreases, as each connections consumes extra server resources for handling and responding to their requests. This is normal behaviour and dependent of the hardware capacity of the server subject to the tests.

 

 

Fig. 2 Report ACT ASP 3.0 Web Application

 

The results of this graphic are easy to interpret. All of my tests were done using 1, 2, 4, and 8 concurrent users. My configuration did not allow me to test with higher amounts of concurrent users. I used a Dell GX-260 for the Web Server, and a Dell GX-240 for the MS SQL Server database (NorthWind). I ran ACT from the SQL server database machine, as this was my only option, and I could do that because I only was interested in the Web Server results.

 

As you can see from the above graph, as the concurrent connections grow, the maximum throughput or RPS bogs down a bit because of the extra need for server resources to handle each request. Increasing the hardware capacity (CPU, RAM, Network Bandwidth) will increase the maximum RPS linearly if the scalability of the Web Application permits that.

 

How does this compare with a similar initial ASP.NET implementation?

 

The next thing I did was to create a similar Web App in ASP.NET with exactly the same functionality, but using the new way of programming in ASP.NET. The language I chose was C#, but for performance reasons it could have easily been programmed using VB.NET, or another (compiled) language supported by ASP.NET.

 

The new .NET project is called "ASPClassic2dotNET" and (if you would like to use VS.NET) can easily be built on your machine by copying the project from the download material to your local web application root, and after having created the application using Internet Service Manager (ISM) open up the "ASPClassic2dotNET.csproj" project file.

 

This should open up the project correctly. I do not recommend opening the file "ASPClassic2dotNET.sln" as it may very well contain a wrong web application path, and thus will very likely generate an error if you do attempt to open it.

 

You can also opt to edit the .sln file and change the path to the one you use, before attempting to open the project in VS.NET. That should work also. The .sln file will be saved and overwritten when you run or save the project.

 

If you do not have VS.NET you can always install the free available Web Matrix Project, or simply use Notepad.

 

Once opened up, you should now be able to locate the default page, "Default.aspx". This page contains the following code, which will be discussed in more details below:

 

<%@ Import Namespace="System.Web" %>

<%@ Import Namespace="System.IO" %>

<%@ Import Namespace="System.Xml.XPath" %>

<%@ Import Namespace="System.Xml.Xsl" %>

<%@ Import Namespace="System.Xml" %>

<script language="C#" runat="server">

 

      public void Page_Load(Object sender, EventArgs E)

      {

 

            /// *************************************************** ///

            /// First performance test                              ///

            ///                                                     ///

            /// NOTE: Make sure debug mode is off!                  ///

            ///                                                     ///

            /// *************************************************** ///

 

            /// loading the XML source document

            /// using SQLXML 3.0 support for MS SQL DB access over HTTP

            string strXml = "http://localhost/aspclassic2dotnet_

  sqlxml/templates/customers.xml";

            XmlDocument doc = new XmlDocument();

            doc.Load(strXml);

 

            /// load the XSL stylesheet

            string xslPath = Server.MapPath("/aspclassic2dotnet/xsl/_

  customers.xsl");

            XslTransform transform = new XslTransform();

            transform.Load(xslPath);

            transform.Transform(doc, null, Response.OutputStream);

 

            /// *************************************************** ///

 

      }

 

</script>

 

After the initial namespaces are imported, the page contains a script which runs on the server side and which contains the code for the Page_Load() event:

 

      string strXml = "http://localhost/aspclassic2dotnet_

  sqlxml/templates/customers.xml";

      XmlDocument doc = new XmlDocument();

      doc.Load(strXml);

 

These three lines load the XML Source Document, formed by MS SQL Server. Then, the XSL Stylesheet physical path string is formed:

 

      string xslPath = Server.MapPath("/aspclassic2dotnet/xsl/_

  customers.xsl");

 

Then, the XslTransform object is instantiated, and the Stylesheet is loaded. After that the XSLT is applied, and the resulting output is written out to the Response Output Stream:

 

      XslTransform transform = new XslTransform();

      transform.Load(xslPath);

      transform.Transform(doc, null, Response.OutputStream);

 

Once again, using ACT results in the following graphics, making clear how well our application performs this time:

 

 

Fig. 3 Report ACT for ASP.NET Web Application

 

What do we see here – is there a better overall application performance when using ASP 3.0?? Yes, there is!!

 

You'll see it better when we compare the classic and ASP.NET results - we can use ACT to do this with ease, and produce the following graph, by selecting the results of both tests in one single graph:

 

 

Fig. 4 Combined ACT report on Classic ASP 3.0 & ASP.NET Web Application

 

This graphic clearly shows that the classic ASP 3.0 approach wins over the ASP.NET approach. Hey – isn't this what it was NOT supposed to be?? How can ASP.NET be so relatively slow even when the page is compiled? What is actually happening here? Did I test it correctly? Even the scalability looks worse – what was the cause of that then?

 

Yes, many questions did arise at the time I did the test. The problem was not the hardware – I used the same configuration for both ACT tests. The problem was not functionality – both applications are functionally equivalent. The problem was not….

 

At that moment I realized that I could use ACT also of course to analyse the ASP.NET Web Application, and see how performance improves when I cut out units of functionality. This would help me in identifying where exactly the performance hits occurred. And that's what I did next. Using ACT, it became clear that some lines of code were heavily responsible for a performance hit. The first step I took was commenting out the following lines of code in the page Analyze01.aspx (see the lines in bold):

 

      /// *************************************************** ///

      /// First analyze test                                  ///

      ///                                                     ///

      ///                                                     ///

      /// *************************************************** ///

 

      string strXml = "http://localhost/aspclassic2dotnet_

  sqlxml/templates/customers.xml";

      XmlDocument doc = new XmlDocument();

      doc.Load(strXml);

 

      string xslPath = Server.MapPath("/aspclassic2dotnet/xsl/_

  customers.xsl");

      XslTransform transform = new XslTransform();

      transform.Load(xslPath);

           

      /// test01

      /// take out the transformation and returning the output only

/// and see the effects using ACT

      // transform.Transform(doc, null, Response.OutputStream);

 

      /// *************************************************** ///

 

 

Then I used ACT again to determine its maximum throughput:

 

 

Fig. 5 ACT report after first analyse step

 

You can easily see that the maximum RPS shows an increase with low concurrent users, but a decrease when more than 5 concurrent users were requesting the page.

 

Then, the second step was taking out the following functionality (again, see the lines in bold):

 

      /// *************************************************** ///

      /// Second analyze test                                 ///

      ///                                                     ///

      ///                                                     ///

      /// *************************************************** ///

 

      string strXml = "http://localhost/aspclassic2dotnet_

  sqlxml/templates/customers.xml";

      XmlDocument doc = new XmlDocument();

      doc.Load(strXml);

 

      /// test02

      /// take out the loading of the stylesheet and the

/// transformation, and once again, see the effects using ACT

      // string xslPath = Server.MapPath("/aspclassic2dotnet/xsl/_

// customers.xsl");

      // XslTransform transform = new XslTransform();

      // transform.Load(xslPath);

 

      /// test01

      /// take out the transformation and returning the output only

/// and see the effects using ACT

      // transform.Transform(doc, null, Response.OutputStream);

 

      /// *************************************************** ///

 

 

And again I used ACT to get the maximum throughput:

 

 

Fig. 6 ACT report after second analyse step

 

Now the overall maximum RPS increased almost over the whole test range, and also showed better scalability.

 

Then, finally I out commented the last bit of code:

 

      /// *************************************************** ///

      /// Third analyze test                                  ///

      ///                                                     ///

      ///                                                     ///

      /// *************************************************** ///

 

      /// test03

      /// take out the loading of the xml, the stylesheet and the

/// transformation, and once again, see the effects using ACT

      /// you should have reached maximum RPS because all the

/// functionality is now outcommented :-)

      // string strXml = "http://localhost/aspclassic2dotnet_

// sqlxml/templates/customers.xml";

      // XmlDocument doc = new XmlDocument();

      // doc.Load(strXml);

 

      /// test02

      /// take out the loading of the stylesheet and the

/// transformation, and once again, see the effects using ACT

      // string xslPath = Server.MapPath("/aspclassic2dotnet/xsl/_

// customers.xsl");

      // XslTransform transform = new XslTransform();

      // transform.Load(xslPath);

 

      /// test01

      /// take out the transformation and returning the output only

/// and see the effects using ACT

      // transform.Transform(doc, null, Response.OutputStream);

 

      /// *************************************************** ///

 

 

Now, the results using ACT were as follows:

 

 

Fig. 7 ACT report after third analyse step

 

See this improvement in maximum RPS? Well, it is so dramatic of course because we just out commented our complete source code, leaving only the framework code for execution. Although it may seem that this last analyse test is not relevant, it shows how high your application throughput can reach when nothing is done at custom code level.

 

Things to improve on the ASP.NET application

 

Good, now at least I had a good understanding where the problems lie and what I could do to improve the application performance. Typically, I found that taking the next series of application changes should highly improve my application's maximum throughput.

 

With each improvement, I tested the overall application performance using ACT, leaving all other parts of the system identical.

 

The first improvement was as follows (again, see the bold lines):

 

      /// *************************************************** ///

      /// First Optimization Phase:                           ///

      /// Adding the XML source                               ///

      ///                                                     ///

      /// *************************************************** ///

 

      XmlDocument doc = (XmlDocument)Cache["aplXmlDocument"];

      if (null == doc)

      {

            string strXml = "http://localhost/aspclassic2dotnet_

  sqlxml/templates/customers.xml";

            doc = new XmlDocument();

            doc.Load(strXml);

            Context.Cache.Insert("aplXmlDocument", doc);

      }

 

      /// load the XSL stylesheet

      // string xslPath = Server.MapPath("/aspclassic2dotnet/xsl/_

// customers.xsl");

      // XslTransform transform = new XslTransform();

      // transform.Load(xslPath);

      // transform.Transform(doc, null, Response.OutputStream);

 

      /// *************************************************** ///

 

As you can see, the XML Source Document is now loaded from an Application variable which is created in the Global.asax file, as follows:

 

Xxx – code Global.asax

 

Now, let's see what ACT pulls out of this change:

 

 

Fig. 8 Performance tests and results after first improvement step

 

Note that the results show a throughput almost equal to the last mentioned results, the third analyse step. This is a big improvement since a lot of the XML source documents needed for display on a web page are static. But what if that's not the case?

 

If you need dynamic XML, load it using the dependency capabilities of the Cache object, either on a file, or by using a trigger on a change in a database INSERT, DELETE, or UPDATE, which will execute an extended procedure, which in turn changes a file on disk that is monitored by the Cache object (sorry there is no better way to do database dependency at the moment, at least no that I know of – just be glad it is possible). An example of using the simple file dependency is shown below when we read in the XSL Stylesheet.

 

Then, the next improvement step was as follows (look for the bold lines again):

 

      /// *************************************************** ///

      /// Second Optimization Phase:                          ///

      /// Adding the XSL source                               ///

      ///                                                     ///

      /// *************************************************** ///

 

      XmlDocument doc = (XmlDocument)Cache["aplXmlDocument"];

      if (null == doc)

      {

            string strXml = "http://localhost/aspclassic2dotnet_

  sqlxml/templates/customers.xml";

            doc = new XmlDocument();

            doc.Load(strXml);

            Context.Cache.Insert("aplXmlDocument", doc);

      }

 

      XslTransform tr = (XslTransform)Cache["aplXslTransform"];

      if (null == tr)

      {

            string xslPath = Server.MapPath("/aspclassic2dotnet/xsl/_

  customers.xsl");

            tr = new XslTransform();

            tr.Load(xslPath);

            Context.Cache.Insert("aplXslTransform", tr, new

  CacheDependency(Server.MapPath("/_

  aspclassic2dotnet/xsl/customers.xsl")));

      }

 

      // tr.Transform(doc, null, Response.OutputStream);

 

      /// *************************************************** ///

 

xxx – explain shortly the use of the CacheDependency here, and in general, the code.

 

Again, we use ACT to determine the maximum throughput:

 

 

Fig. 9 Performance tests and results after second improvement step

 

Again, we see that the maximum throughput stays almost the same –great! Both improvement steps until now used the new ASP.NET object Cache. Obviously, this object can dramatically improve your results!

 

But we are not finished yet: we still need to perform the XSL Transformation, to make the page work like it originally did (see the bold lines):

 

      /// *************************************************** ///

      /// Third (and last) Optimization Phase:                ///

      /// Adding the Transform and output to client           ///

      ///                                                     ///

      /// *************************************************** ///

 

      XmlDocument doc = (XmlDocument)Cache["aplXmlDocument"];

      if (null == doc)

      {

            string strXml = "http://localhost/aspclassic2dotnet_

  sqlxml/templates/customers.xml";

            doc = new XmlDocument();

            doc.Load(strXml);

            Context.Cache.Insert("aplXmlDocument", doc);

      }

 

      XslTransform tr = (XslTransform)Cache["aplXslTransform"];

      if (null == tr)

      {

            string xslPath = Server.MapPath("/aspclassic2dotnet/xsl/_

  customers.xsl");

            tr = new XslTransform();

            tr.Load(xslPath);

            Context.Cache.Insert("aplXslTransform", tr, new

  CacheDependency(Server.MapPath("/_

  aspclassic2dotnet/xsl/customers.xsl")));

      }

 

      tr.Transform(doc, null, Response.OutputStream);

 

      /// *************************************************** ///

 

This last step will show the final improvement we reached after applying all improvement steps:

 

 

Fig. 10 Performance tests and results after third (and final) improvement step

 

OK, now the ASP.NET performance leaves ASP 3.0 behind – that is what we were after, right?

 

But, the final step still is apparently a big performance hit. We could investigate this further by trying out other solutions like for example using the XML Web Server Control. This is a server side .NET control that is capable of showing raw XML (sent as HTML to the client browser) or applying it an XSLT before the output (also HTML) is sent to the browser. This however is left up to you, because the article would be getting rather long that way.

 

As you can see below, where I have made a ‘cleaner’ graphic using ACT to compare both final applications in their best behaviour, you now can clearly see that ASP.NET has become the winner now (Improve03.aspx).

 

 

Fig. 11 Final application performance comparison

 

The reason that the upper line is topped off as of 2 concurrent connections is because of system limits, and thus can easily be improved by increasing hardware and network capacity.

 

The performance increase is per amount of user connections:

 

Connections:

1

2

4

8

ASP 3.0

45.07

55.85

68.05

78.07

ASP.NET

85.98

133.02

135.62

136.03

Performance Increase (%)

 

91

 

138

 

99

 

74

 

This really IS a big improvement, wouldn’t you agree? And since my test did not include scalability, and the three last tests of the improved ASP.NET Web Application indicate that maximum test capacity is reached (the CPU was above 80% with 8 concurrent users on the machine where ACT was ran, while the CPU of the tested machine decreased a bit), the performance increase could be even better when you simply add more hardware in terms of CPU and RAM (most of the time, scalability relates closely to the amount of hardware and network bandwidth that your equipment has), thereby increasing the server’s processing capacity.

 

Conclusion

 

When moving to ASP.NET, be aware that your overall application performance could decrease. On the other hand, this article has (hopefully) shown you how you can increase ASP.NET’s performance dramatically by using the performance improving techniques described herein.

 

Some recommendations regarding whether to seriously consider moving to ASP.NET, especially in the case where you already have an application running smoothly (meaning it has good performance, scalability, and stability) could be:

 

 

 

*****

* Rights Reserved © Pieter Siegers 2003 *

*