very notion of nothingness is completely rewritten by the laws of
quantum physics" --
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
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
- 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
- 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.
- 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
- 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.
- 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 .
"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
- 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
- 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.
- 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
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!