Home > Articles

.NET Performance Mechanisms

This chapter is from the book

This chapter is from the book

.NET Performance Mechanisms

This article is excerpted from Chapter 15, "Performance Tuning in .NET," from .NET e-Business Architecture, by G. A. Sullivan (Sams Publishing; ISBN 0-672-32219-6).

The .NET Framework provides several mechanisms that application developers can use to gain performance boosts. Among these are caching technology in ASP.NET, application profiling, asynchronous processing support, and install-time code generation. By implementing some of these strategies, an application can perform significantly faster. Consider these techniques when designing a new .NET e-Business application.

ASP.NET Caching Technologies

Caching web pages is an important concept to keep in mind when designing a high-performance dynamic web site. Caching is the concept of rendering a page a single time, and then storing the rendered output in memory for fast access thereafter. Caching can offer significant performance gains when implemented appropriately. Pages that are more static in nature, such as the main gasTIX home page, or a product catalog that does not change often, are good candidates for caching.

Output Caching

Output Caching in ASP.NET generates an ASPX page dynamically the first time, making the middle-tier call and the database hit required to fill out the data controls on the page. The page is then stored in memory so subsequent requests are served without traversing the various tiers again.

ASP.NET output caching is configurable on a page-by-page basis, so we should consider turning it on for the more static pages on our sites. The following directive, placed at the top of an ASPX page, will place this page in the output cache for five minutes (300 seconds):

<%@OutputCache Duration="300" VaryByParam="None" %>

Caching parameters for an ASPX page can also be set in the code-behind page using the Response.Cache properties. However, it is simpler to use the @OutputCache page directive and let ASP.NET handle the details.

The VaryByParam argument of the @OutputCache directive can be used to cache multiple versions of the same page. Dynamic pages often return different results based on the parameters passed in the QueryString or in a form post. Use the VaryByParam option to tell ASP.NET which parameters passed into the page will cause another version of the page to be cached. For example, in the gasTIX application, the main home page lists subcategories the user can pick. When a subcategory is chosen, such as Celtic under the Music category, the following URL is requested:


Note the SubCategory_ID and SubCategory_Name parameters passed in the QueryString. We can choose to create a cached version of the ParticipantsBySubCategory.aspx page for each SubCategory_ID passed in by adding the following directive to the top of the page:

<%@OutputCache Duration="300" VaryByParam="SubCategory_ID" %>

If we need to cache an ASPX page for multiple parameters, we can semi-colon delimit the parameter list in the VaryByParam option.

We can also choose to cache Web Form User Controls independently from the ASPX page on which they are placed, effectively making it possible to cache only specific portions of a page.

Application Cache

Two other options are available in ASP.NET to cache data that is expensive to generate. Information can be stored in the Application object (System.Web namespace, HttpApplicationState class), or in the Cache object (System.Web.Caching namespace, Cache class). Both methods enable storing data across multiple web page requests, and both are scoped according to the application. Web pages in one application domain on the same web server cannot access the data in another application's cache.

The Application object is similar to its predecessor in ASP, and it is in fact backwards compatible with that version. This is helpful when we decide to migrate our ASP applications to ASP.NET—we are not required to worry about changing the guts of our application state mechanism.

The Cache class takes key/value pairs, and supports special functionality to optimize its use. It will clean itself up when system resources run low (similar to .NET CLR garbage collection), removing items that have not been used in some time. This built-in technique is called scavenging. We can set the expiration time of a specific item in the cache, and can also set a priority level that determines if other items are scavenged first.

The Cache class also enables a developer to specify a dependency on a file or on another cached item when creating a new cache entry. When the dependent item changes, the cached item with the specified dependency is removed from the cache, keeping data in synch. We could, for example, cache a list of the events in a tour on gasTIX setting a dependency on an XML file containing the tour cities. When we update the XML file to add new cities to a tour, the cached item will expire because the XML file on which it is dependent has been modified. The next user request for the tour list will cause ASP.NET to re-generate the item and place it in the cache.

.NET Application Profiling

Profiling an application in .NET is the concept of monitoring different aspects of its behavior while it is running, preferably under load. The various aspects we can monitor can be categorized into two groups: system-provided and application-provided.

System-provided counters are built-in to the Windows operating system, and allow us to monitor processor, memory, and disk usage, SQL Server locks and connections, ASP.NET page requests, and much more.

.NET Performance Counters

The .NET Framework provides us with a large number and variety of new performance counters that can help us track down problems with our .NET applications. These counters and their descriptions are shown in Table 15.1.

Table 15.1 .NET Performance Counters

Performance Object

Description (per .NET Framework SDK)

.NET CLR Exceptions

Exceptions are violations of semantic constraints of an implementation language, the runtime, or an application.

.NET CLR Interop

Interoperability deals with how the runtime interacts with all external entities, including COM, external libraries, and the operating system.


Just-in-time (JIT) compilation is used to compile IL methods to native machine language immediately before execution of the methods.

.NET CLR Loading

Loading is the process used to locate a binary form of a class and constructing from that binary form an object that represents the class.

.NET CLR LocksAndThreads

A lock, or mutex, is data associated with each object in the runtime that a program can use to coordinate multithreaded access to the object. A thread is an independent unit of execution with its own working memory that operates on values and objects that reside in a shared main memory.

.NET CLR Memory

Memory is the set of storage locations that a program uses to store its variables.

.NET CLR Remoting

Remoting is the mechanism used to make method calls between object instances across a boundary. Boundaries include calling between contexts, application domains, processes, and machines.

.NET CLR Security

Security is the set of mechanisms used to provide controlled access to resources.


ASP.NET global performance counters are exposed which either aggregate information for all ASP.NET applications on a Web server computer or apply generally to the ASP.NET subsystem.

ASP.NET Applications

ASP.NET application performance counters can be used to monitor the performance of a single instance of an ASP.NET application. A unique instance appears for these counters, named __Total__, which aggregates counters for all applications on a Web server (similar to the global counters). The __Total__ instance is always available—the counters will display zero when no applications are present on the server.

Although the system-provided performance counters give us a wealth of information with which to profile our .NET applications, we might want to implement a few custom counters to help determine bottlenecks, or to provide administrators with general operational feedback. They can provide us with special insight into the workings of our custom application that is not possible with the Windows 2000 system-provided counters.

Application-provided performance counters are built into our code. We define categories and counters and choose when to increment or decrement our counter values. When we set our code in motion, we can watch our custom counters in action based on the application events that occur.

Application-provided counters are implemented using the classes located in the System.Diagnostics namespace. To implement a custom counter, implement code similar to that found in Listing 15.1.

Listing 15.1 Creating a Custom Application Performance Counter in .NET is Done through the System.Diagnostics Namespace

using System;
using System.Diagnostics;

namespace gasTIXConsole
  class Class1
    static void Main(string[] args)
      // first check to see if the category is already there
      if (!PerformanceCounterCategory.Exists("gasTIX") ||
 !PerformanceCounterCategory.CounterExists("TicketsSold", "gasTIX"))

"The gasTIX performance counters report on a large variety of gasTIX metrics.",

"This counter reports the number of overall tickets sold on the gasTIX site.");

      PerformanceCounter pcTicketsSold = new PerformanceCounter("gasTIX", "TicketsSold", false);

      // this loop would of course be replaced with a real ticket sale event
      for (int i=1; i <= 90000; i++)

Once the custom performance category and counters have been implemented, we can start monitoring using the Performance Monitor tool (described in more detail in the next section), shown in Figure 15.1.

Figure 15.1. A custom counter is displayed in Performance Monitor.

Performance Monitor

The main tool used to track both system- and application-provided performance counters is the Windows Performance Monitor utility. To run this utility, enter perfmon in the Start/Run dialog box, or select Performance from the Administrative Tools program group.

The Performance Monitor lets us add the counters relevant to the situation we are monitoring. By choosing a few counters while our application is running (or while it is being stress-tested by a tool such as the Application Center Test tool), we can watch the counters to see if they provide insights into why our application might not be performing as we desire. Picking a few sample counters with this tool is shown in Figure 15.2.

Figure 15.2. The Performance Monitor allows us to track system and application performance metrics.

We can also record a Performance Monitor session so we can play it back later. This is helpful for recording performance on production servers. The results can be brought down to a local server and re-run to keep the production server from being significantly impacted.

After we have made a modification to an ASPX file or we have added more RAM to a server, we should use the same counters and run the same tests to see if we have helped remove the bottleneck. Performance Monitor allows us to save a group of counters so we can quickly recall an entire counter group.

A thorough grounding in application profiling, creating, updating, and measuring performance counters, is a key to enhancing the performance of our .NET e-Business applications. The Performance Monitor is our main window into both system- and application-provided performance counters, so we should become quite familiar with this tool.

Asynchronous Processing in .NET

Many times an application can offload work to a background process so the user can go on to other tasks. The user can return later to view the status of the background process, or he can be notified through a mechanism such as e-mail. Consider implementing asynchronous processing where appropriate to improve overall application performance.

Business workflow is often a good candidate for asynchronous processing. Using gasTIX as a practical example, when a user completes a purchase, an entire series of business events needs to take place—notifying the fulfillment partner, exporting to the accounting system, notifying the artist, etc. The user does not want to wait for the web browser screen to refresh while all these events take place. Perhaps the communication link between the gasTIX systems and the fulfillment partner is temporarily down. The user just wants to know the order was placed, and to go on doing other things.

Such business events could be handled asynchronously in the background after saving the transaction information to the database and returning control to the user. Any errors encountered in the asynchronous process can be logged or sent via notification to an administrator. The user will perceive a more robust and high-performance system with such an asynchronous design.

Install-Time Code Generation

Microsoft provides a utility called Ngen.exe that allows an administrator to pre-compile (pre-JIT) IL application code into native machine language code after installation. This technique is called "install-time code generation".

The advantage of pre-compiling assemblies is the time it takes to invoke a segment of code at run-time is reduced. This is because the compilation to native machine language has already taken place at install-time. We take the performance hit during the Ngen run, rather than at application run-time.

The Ngen utility, shown in Figure 15.3, is called for all the assemblies (DLLs) we want to pre-compile. The results are placed in a reserved area called the native image cache.

Figure 15.3. Running Ngen.exe on each gasTIX assembly.

To confirm our assemblies have been pre-compiled and have been placed in the native image cache, we can run the Ngen command again with the /show parameter.

For ease of use, it is appropriate to create a batch file with the Ngen command specifying all the assemblies to pre-compile. This will allow the administrator to simply double-click the batch file to run the install-time code generation process.

Another way to determine whether the assemblies are pre-JIT compiled or will be JIT compiled on demand at runtime is to view the C:\WINNT\Assembly folder in Windows Explorer, as shown in Figure 15.4.

Figure 15.4. Windows Explorer lists the native image cache in the GAC.

When viewing this folder in Windows Explorer, a shell extension is invoked that categorizes the assembly types as either PreJit or normal (blank). The true directory structure on disk is a bit different, however. Using a command prompt to browse to the C:\WINNT\Assembly folder, we can see there are really a few different subfolders at this location.

Figure 15.5. The native image cache is stored in a different subdirectory from the GAC.

The assemblies we compiled using the Ngen tool have been placed into the NativeImages1_v1.0.2914 folder, while the Global Assembly Cache shared assemblies are located in the GAC folder. Although in Windows Explorer it appears the native image cache is a part of the GAC, this is not in fact the case. They do share some similarities, however, such as persistence on disk when a machine reboots. This is different from JIT-compiled code, which is stored in memory and is lost when the owning process dies.

We should consider using the Ngen utility to pre-compile .NET code that takes a long time to start. This can help the users of our applications, especially the ones who first hit a page or function, get a performance boost.

Other .NET Performance Considerations

When working with specific pieces of the .NET Framework, we need to keep in mind a few techniques that will ensure a high performance system. This section covers the most important .NET tools and techniques that fall into this category.


ASP.NET introduces a new feature that maintains the state of server controls on a web form between page postbacks called ViewState. Although this feature comes in quite handy and saves us from writing lots of extra code, it should be used wisely. The ViewState feature can increase the size of an ASPX page substantially, especially when used with repeating data controls like DataGrid and DataList.

Turn off ViewState on a control-by-control basis using the MaintainState parameter. It should be set to false when we do not need ASP.NET to remember control state between server trips. The default setting for ViewState is true. Turn off ViewState for an entire ASPX page by using the EnableViewState in the @Page directive:

<%@Page Language="VB" EnableViewState="False" %>

Session State

Internet Information Server (IIS) session state should also be disabled when not needed. This can be done on a page-by-page basis with the following page directive:

<@Page EnableSessionState="false" %>

Session state generates a cookie sent over the HTTP header. This generation requires extra CPU cycles to perform, and if we are not using session variables on a page, we should disable it to get a performance boost.

Some ASPX pages may only need to read from Session variables. If this is the case, we can make the session state read-only with the following page-level directive:

<@Page EnableSessionState="ReadOnly" %>

In-process session state is the fastest option when state persistence is required in an application. However, it is also the least fault-tolerant, because it runs in the same process space as IIS. If IIS crashes, the session state will be lost. ASP.NET offers an out-of-process Session Windows service, which can be located on a completely separate machine. Additionally, state can be stored in SQL Server. Although these alternatives are more fault-tolerant, they are slower. We need to evaluate the speed requirements of our applications when deciding which state option to implement.


Use the new StringBuilder class of the System.Text namespace for efficient string concatenation. Concatenations have been the bane of Visual Basic 6.0 programmers because of the inefficient way in which memory was used to perform the operation. StringBuilder offers a remedy to this situation, providing fast and efficient memory usage during operation.

Visual Basic .NET programmers no longer have to worry about performance degradations when concatenating with StringBuilder. The code in Listing 15.2 demonstrates a simple use of the StringBuilder class:

Listing 15.2 The New StringBuilder Class Offers Performance Benefits Over Simple String Concatenation

using System;
using System.Text;

namespace gasTIXConsole
  class Class1
    static void Main(string[] args)
      StringBuilder tmpTickets = new StringBuilder();
      String tmpMyString = " this is number: ";
      for (int i=1; i <= 100; i++) {

Secure Sockets Layer (SSL)

The Secure Sockets Layer (SSL) protocol, or HTTPS, should only be used when necessary. On gasTIX, the appropriate pages for SSL implementation are the order and order confirmation pages, on which credit card information is passed between the user's browser and the gasTIX web server over the Internet. It may be easier programmatically to turn on SSL for an entire web site, but using SSL where not really needed will frustrate users because of the performance hit taken for each page request.

Newer SSL accelerator technology can offload the CPU cycles it takes to encrypt and decrypt the HTTPS stream. One of these new products, BIP-IP from F5 Networks provides such functionality, speeding up the process by letting the CPU on the Web server focus on page generation, rather than on encryption. Intel's new Itanium chip supports on-chip SSL processing, also speeding throughput.

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information

To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.


Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.


If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information

Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.


This site is not directed to children under the age of 13.


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information

If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information

Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents

California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure

Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact

Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice

We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020