Book Review: Improving .NET Application
Performance and Scalability
[Microsoft]
by Peter A. Bromberg, Ph.D.

Peter Bromberg

"The very notion of nothingness is completely rewritten by the laws of quantum physics" -- Brian Greene

Microsoft has embarked on a mission for putting together their "Patterns and Practices" whitepapers and materials into book form, and "Improving .NET Application Performance and Scalability", by J.D. Meier, Srinath Vasireddy, Ashish Babbar and Alex Mackman is going to become a bestseller as soon as more people find out about it.



In sum, this is 17 chapters and over 1,000 pages plus appendixes and "How to's" on every possible facet of .NET Framework development, with a singular focus on best practices and performance. Not only is this book well - organized, it also tells you both what you should be doing and most importantly, it explains why you should do it.

Chapters in the book are laid out as follows in five parts:

Part I, Fundamentals of Engineering Performance

  • Chapter 1, " Fundamentals of Engineering for Performance "

Part II, Designing for Performance

Performance modeling helps you assess your design choices before committing to a solution. By considering from the start your performance objectives, workload, and metrics for your scenarios, you reduce risk. Use the design guidelines chapter to learn practices, principles, patterns, and anti-patterns that will help you to make informed choices. Part II includes three chapters:

  • Chapter 2, " Performance Modeling "
  • Chapter 3, " Design Guidelines for Application Performance "
  • Chapter 4, " Architecture and Design Review of a .NET Application for Performance and Scalability "

Part III, Application Performance and Scalability

This part provides a series of chapters that provide deep platform knowledge across the .NET Framework technologies. Use these chapters to learn about the key performance and scalability considerations for the various .NET technologies, and to improve the efficiency of your code in these areas. Part III includes nine chapters:

  • Chapter 5, " Improving Managed Code Performance "
  • Chapter 6, " Improving ASP.NET Performance "
  • Chapter 7, " Improving Interop Performance "
  • Chapter 8, " Improving Enterprise Services Performance "
  • Chapter 9, " Improving XML Performance "
  • Chapter 10, " Improving Web Services Performance "
  • Chapter 11, " Improving Remoting Performance "
  • Chapter 12, " Improving ADO.NET Performance "
  • Chapter 13, " Code Review: .NET Application Performance "

Part IV, Database Server Performance and Scalability

This part shows how to improve SQL Server performance. This part includes one chapter:

  • Chapter 14, " Improving SQL Server Performance "

Part V, Measuring, Testing, and Tuning

This part shows which metrics monitor and analyze for specific performance aspects. It also explains how to load, stress, and capacity test your applications and how you can tune performance with appropriate application, platform, and system configuration. This part includes three chapters:

  • Chapter 15, " Measuring .NET Application Performance "
  • Chapter 16, " Testing .NET Application Performance "
  • Chapter 17, " Tuning .NET Application Performance "

Clearly, this is the single most comprehensive guide to performance - oriented best practices for the .NET platform ever put together by any publisher. It doesn't matter how advanced you are with .NET - you will find plenty of eye-openers in this book.

Just for starters, lets' go over a short list of some of the items covered in Chapter 6, "Improving ASP.NET Performance". This isn't a complete list, just some snippets so you can get a feel for the depth of coverage. All the other chapters are as good or better.

 Objectives

  • Improve page response times.
  • Design scalable Web applications.
  • Use server controls efficiently.
  • Use efficient caching strategies.
  • Analyze and apply appropriate state management techniques.
  • Minimize view state impact.
  • Improve performance without impacting security.
  • Minimize COM interop scalability issues.
  • Optimize threading.
  • Optimize resource management.
  • Avoid common data binding mistakes.
  • Use security settings to reduce server load.
  • Avoid common deployment mistakes.

Performance and Scalability Issues

  • Resource affinity . Resource affinity can prevent you from adding more servers, or resource affinity can reduce the benefits of adding more CPUs and memory. Resource affinity occurs when code needs a specific thread, CPU, component instance, or server.
  • Excessive allocations . Applications that allocate memory excessively on a per-request basis consume memory and create additional work for garbage collection. The additional garbage collection work increases CPU utilization. These excessive allocations may be caused by temporary allocations. For example, the excessive allocations may be caused by excessive string concatenation that uses the += operator in a tight loop.
  • Failure to share expensive resources . Failing to call the Dispose or Close method to release expensive resources, such as database connections, may lead to resource shortages. Closing or disposing resources permits the resources to be reused more efficiently.
  • Blocking operations . The single thread that handles an ASP.NET request is blocked from servicing additional user requests while the thread is waiting for a downstream call to return. Calls to long-running stored procedures and remote objects may block a thread for a significant amount of time.
  • Misusing threads . Creating threads for each request incurs thread initialization costs that can be avoided. Also, using single-threaded apartment (STA) COM objects incorrectly may cause multiple requests to queue up. Multiple requests in the queue slow performance and create scalability issues.
  • Making late-bound calls . Late-bound calls require extra instructions at runtime to identify and load the code to be run. Whether the target code is managed or unmanaged, you should avoid these extra instructions.
  • Misusing COM interop . COM interop is generally very efficient, although many factors affect its performance. These factors include the size and type of the parameters that you pass across the managed/unmanaged boundary and crossing apartment boundaries. Crossing apartment boundaries may require expensive thread switches.
  • Large pages . Page size is affected by the number and the types of controls on the page. Page size is also affected by the data and images that you use to render the page. The more data you send over the network, the more bandwidth you consume. When you consume high levels of bandwidth, you are more likely to create a bottleneck.
  • Failure to use data caching appropriately . Failure to cache static data, caching too much data so that the items get flushed out, caching user data instead of application-wide data, and caching infrequently used items may limit your system's performance and scalability.
  • Failure to use output caching appropriately . If you do not use output caching or if you use it incorrectly, you can add avoidable strain to your Web server.
  • Inefficient rendering . Interspersing HTML and server code, performing unnecessary initialization code on page postback, and late-bound data binding may all cause significant rendering overhead. This may decrease the perceived and true page performance.

Design Considerations

  • Consider security and performance .
  • Partition your application logically .
  • Evaluate affinity .
  • Reduce round trips .
  • Avoid blocking on long-running tasks .
  • Use caching .
  • Avoid unnecessary exceptions .

Reduce Round Trips

  • HttpResponse.IsClientConnected .
  • Caching .
  • Output buffering .
  • Server.Transfer .
  • Response.Redirect

    "Tuning .NET Application Performance."

    • Set maxconnection to 12 * # of CPUs . This setting controls the maximum number of outgoing HTTP connections that you can initiate from a client. In this case, ASP.NET is the client. Set maxconnection to 12 * # of CPUs.
    • Set maxIoThreads to 100 . This setting controls the maximum number of I/O threads in the .NET thread pool. This number is automatically multiplied by the number of available CPUs. Set maxloThreads to 100.
    • Set maxWorkerThreads to 100 . This setting controls the maximum number of worker threads in the thread pool. This number is then automatically multiplied by the number of available CPUs. Set maxWorkerThreads to 100.
    • Set minFreeThreads to 88 * # of CPUs . This setting is used by the worker process to queue all the incoming requests if the number of available threads in the thread pool falls below the value for this setting. This setting effectively limits the number of requests that can run concurrently to maxWorkerThreads minFreeThreads . Set minFreeThreads to 88 * # of CPUs. This limits the number of concurrent requests to 12 (assuming maxWorkerThreads is 100).
    • Set minLocalRequestFreeThreads to 76 * # of CPUs . This setting is used by the worker process to queue requests from localhost (where a Web application sends requests to a local Web service) if the number of available threads in the thread pool falls below this number. This setting is similar to minFreeThreads but it only applies to localhost requests from the local computer. Set minLocalRequestFreeThreads to 76 * # of CPUs.

    The above recommendations are much different from the default settings. A complete explanation and methodology is provided in the book.

Threading Guidelines

  • Tune the thread pool by using the formula to reduce contention .
  • Consider minIoThreads and minWorkerThreads for burst load .
  • Do not create threads on a per-request basis .
  • Avoid blocking threads .
  • Avoid asynchronous calls unless you have additional parallel work .

Chapter 6, alone, is 75 pages packed with specific do's and dont's related to ASP.NET performance, best practices coding architecture, and tuning.

I would normally say something like "I learned a lot from this book". The fact of the matter is, this book is so totally jam-packed with valuable knowledge that I'll be learning a lot more each day. Absolutely recommended reading for any professional .NET developer, regardless of skill level!

The sticker price on this puppy is $59.95, but it is available at various discounters such as Bookpool.com at $33.95 It's also available online at MSDN and even as a free 8MB PDF download. But, you won't be able to sit in bed reading those at night with a yellow highliter!

 



Peter Bromberg is a C# MVP, MCP, and .NET consultant who has worked in the banking and financial industry for 20 years. He has architected and developed web - based corporate distributed application solutions since 1995, and focuses exclusively on the .NET Platform.
Article Discussion: