Building 20high 20performance 20applications
Document Sample


Building high performance
applications with .NET
Tom Hollander
Microsoft
Agenda
Performance and scalability overview
Performance modelling
Designing for performance
Coding for performance
Finding and fixing performance problems
Performance and Scalability
Performance:
A measure of a system’s ability to respond to
requests within a defined time interval, under
real conditions
Scalability:
How well a solution to some problem will work
when the size of the problem increases
Performance in the software
lifecycle
Performance is not the only consideration,
but it always matters
Needs to be considered throughout the
software lifecycle: architecture, design,
development, testing, deployment
Tuning at the end can only help so much
Designing for performance
Performance is a feature – you need to
design for it like you would anything else
Fixing coding problems is relatively easy –
fixing design problems is almost
impossible late in the cycle
Don’t prematurely optimise, but validate
and measure performance as you design
and prototype
Design for performance
Service factoring and interface design
Machine and process partitioning
Sync, async, batch processing
Parallel processing
Stateless design
Long-running transactions
Algorithm design
Data persistence and caching
OO Purity
.NET CLR – Memory Management
Minimise frequent object allocations
Release expensive objects as early as possible
Don’t force the Garbage Collector to run
Whenever you use an object which implements
IDisposable within a single method, call Dispose when
you’re finished
Or you can call an equivalent method, such as Close
Do it in a Finally block
Use the using() syntax in C# to make this easy
If your class has any member variables that implement
IDisposable, implement IDisposable on your class too
Memory Management Example
1
Private Sub WriteFile()
Dim writer As New
System.IO.StreamWriter("test.txt")
Try
writer.WriteLine("Hello world!")
Finally
writer.Close() ' equivalent to calling Dispose
End Try
End Sub
Memory Management Example
2
Public Class MyResource
Implements IDisposable
Private component As Component ‘ A managed, disposable resource
Private disposed As Boolean = False ‘ Has Dispose been called?
Public Sub New()
component = New Component() ‘ You would use a more useful object!
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
If Not disposed Then ‘ Allow Dispose to be called multiple times
If Not component Is Nothing Then
component.Dispose() ‘ And any other clean up you might require
End If
disposed = True
End If
End Sub
End Class
.NET CLR – Memory Management
Never implement a finaliser unless you absolutely need
to
Always implement a finaliser on your class if it wraps
unmanaged resources
If you implement a finaliser on your class, always
implement the IDisposable interface as well
call GC.SuppressFinalizer(Me) in Dispose
If you implement a finaliser on your class, always call
your base class’s finaliser (not needed in C# destructors)
Don’t touch other managed objects in finaliser code
.NET CLR – Types
Only use value types (Structures) for small
amounts of data
Minimise boxing and unboxing
Don’t create too many strings
Avoid concatenation, use StringBuilder for
5+ strings (particularly in loops)
.NET CLR – Collections
Choosing a List collection type:
Use an Array if the size is never going to change
Use an Array if you are storing value types and need
to minimise boxing
Use an ArrayList if you need to add or remove items,
and you don’t want to sort data frequently (you can
use the Sort method to sort the data when required)
Use a SortedList if you always need the data to be
sorted
Use a StringCollection if you want ArrayList
behaviour and you are only storing strings
.NET CLR – Collections
Choosing a Dictionary collection type:
Use a Hashtable if you expect you will be storing
more than 10 items
Use a ListDictionary if you know you will be storing
up to 10 items
Use a HybridDictionary if you don’t know how many
items you will have
Use a StringDictionary if the values you store are
always strings
.NET CLR – Collections
the right size if you
Initialise collections to
have some idea on how many you need:
Dim ht As New Hashtable(43)
Be efficient with what you put in collections
The difference between storing Short and
Long variables is huge if you have an array of
a million items!
.NET CLR – Exceptions
Minimise the throwing of exceptions
Only catch an exception if you think you
can add value
Logging
Throwing a more applicable exception
Recovering (or attempting to recover)
It’s OK to let exceptions bubble
.NET CLR – Reflection
Minimise the use of reflection
Don’t use late binding in Visual Basic
Dim o As Object = New _
System.Data.SqlClient.SqlConnection
o.ConnectionString = _
"database=northwind;server=mySQLServer"
o.Open()
Turn Option Strict On to disallow late
binding
.NET CLR – Threading
Minimise thecreation of threads
Use the ThreadPool class
Make your code threadsafe, but don’t lock
too much
This applies when you create your own
threads, use Shared/static members, or
Singleton objects and services
Threading example
Private Shared myCollection As New Hashtable()
Private Sub DoStuff()
Dim item As Object
SyncLock myCollection.SyncRoot
For Each item In myCollection
' Access the items...
Next item
End SyncLock
End Sub
Data Access – Transactions
Don’t use explicit transactions if you don’t need
to
Use SQL transactions for server controlled
transaction on single data store
Use ADO.NET transactions for client controlled
transaction on single data store
Use COM+ distributed transactions for writes to
multiple data stores
Keep transactions as short as possible
Use the appropriate isolation level
Data Access – Stored Procs
Use Stored Procedures instead of
dynamic SQL
Explicitly set parameters and their data
types
Use SqlHelperParameterCache when
using the Microsoft Data Access
Application Block
SET NOCOUNT ON
Parameters Example
' Worse performing version
SqlHelper.ExecuteNonQuery(connectionString, _
CommandType.StoredProcedure, _
"spAddMilkshake", _
New SqlParameter("@Flavour", "Pineapple"), _
New SqlParameter("@Kilojoules", 600), _
New SqlParameter("@Delicious", True))
Parameters Example
' Better performing version
SqlHelper.ExecuteNonQuery(connectionString, _
CommandType.StoredProcedure, _
“dbo.spAddMilkshake", _
New SqlParameter("@Flavour",
SqlDbType.NVarChar, 255).Value = "Pineapple", _
New SqlParameter("@Kilojoules",
SqlDbType.Int).Value = 600, _
New SqlParameter("@Delicious",
SqlDbType.Bit).Value = True)
Data Access – Connections
Use Connection Pooling
Happens automagically - no need to use
COM+
Can be tuned with connection string
Use the SqlClient managed provider if
portability isn’t an issue
Close Connections, DataReaders, and
other Disposable objects
Connection Example
Dim reader As SqlDataReader
Try
reader = SqlHelper.ExecuteReader(connectionString, _
CommandType.StoredProcedure, "spGetAllMilkshakes")
While reader.Read()
Console.WriteLine("Flavour: " & reader.GetString(0))
End While
Finally
If Not reader Is Nothing Then
reader.Close() ' Connection will be closed by DAAB
End If
End Try
Data Access – Queries
Use the right Execute method on
Command objects and SqlHelper
Choosing DataSet or DataReader
Only return the columns and rows you
need
Don’t infer Dataset schemas at runtime
Minimise round-trips to the database
Enterprise Services (COM+)
Only use Enterprise Services if you need
to
Use object pooling only if creating objects
is relatively expensive
Use Library Applications if possible
Do not maintain state
XML
Use the right parsing method:
XmlReader-derived classes for forward-only,
read-only access
XPathDocument for random access, read-
only access
XmlDocument (DOM) only if you need to
modify the document
Minimise parsing of XML documents
ASP.NET – General tips
Check Page.IsPostBack to minimise
redundant processing
Reduce roundtrips using Server.Transfer
instead of Response.Redirect
Minimise page sizes
Text and Markup
ViewState
Images
ASP.NET – ViewState
Turn Off ViewState unless you need it
Per control:
<asp:datagrid EnableViewState="false" />
Per page:
<@ page EnableViewState="false">
Per application:
<Pages EnableViewState="false" />
(in web.config)
ASP.NET – Caching
ASP.NET can cache entire pages or
fragments
<%@ OutputCache Duration="10"
VaryByParam="none"%> in .aspx or .ascx
file
VaryByParam, VaryByControl,
VaryByHeader and VaryByCustom
supported
<PartialCaching(120)> in code behind
ASP.NET – Session State
Turn off session state if you aren’t using it
<%@ Page EnableSessionState = "false">
<%@ Page EnableSessionState =
"ReadOnly">
Don’t store too much in session state
Finding performance problems
Test as you go – not just at the end
Types of tests:
Load testing – testing with expected number of users
Stress testing – test over a long period, cranking up
the number of users until it breaks
Capacity testing – measuring resource usage for a
given user load
Measure both throughput and latency
Tools
Profiling tools– gives you a look inside the
application (objects, call stacks, time
taken, …)
Monitoring tools – monitor external
resources (network, memory, disk, CPU,
…)
Load testing tools – generate load on your
application, measure response time and
throughput
Tools
Profiling tools:
Microsoft CLR Profiler (free!)
Compuware DevPartner Community Edition
(free!)
Microsoft AutoDump+ (free! but tricky…)
Compuware DevPartner Studio
Borland OptimizeIt
IBM Rational Quantify
Compuware DevPartner
Tools
Monitoring tools:
Windows Performance Monitor (included with
Windows)
Network Monitor (free!)
Performance Monitor
Tools
Load testing tools:
Application Center Test (included with
VS.NET)
Mercury LoadRunner
Compuware QALoad
Application Center Test
Questions?
Get documents about "