About Juval LöwySoftware architect
Consults and trains on .NET migration and design
MS Regional Director for the Silicon Valley
AuthoredProgramming .NET components (2003, O’Reilly)
COM and .NET component services (2001, O’Reilly)
Participates in the .NET design reviews
Contributing editor and columnist to the Visual Studio Magazine
Contact at www.idesign.net
Agenda
Definitions
.NET benchmarks
Design and measurement
Examples in everyday Code
Less known/understood examples and best practices
Resources
What is Performance
My Answer: how the application performs Not just raw “performance”
Performance How long it take to perform a request
ScalabilityHow many outstanding clients
ThroughputHow many concurrent request
What is Performance
Responsiveness How long a client waits to be serviced
AvailabilityHow much of the time the app is up
ConsistencyProportion of aborted transactions
Security How secure is the application
Cost Hardware is expensive
.NET Benchmarks
Pets shop.NET 1.0Done by Microsoft Partner
Pets shop.NET 2.0Done by Middleware Company
J2EE industry and community leader
Suspected Web Sphere and Web Logic
http://www.middleware-company.com/j2eedotnetbench/
.NET Benchmarks Highlights (.NET 1.1 on Windows Server 2003)
PerformanceOutperforms J2EE by 339%
Outperforms J2EE by 98% on distributed transactionat 1/4 cost per transaction
Outperforms J2EE by 331% in XML Web Service testing
Productivity
Productivity1/6 cost to implement in .NET
Optimizing/configuring J2EE application server 10 man-weeks per application server with .NET at 2 man-weeks
Web Pages ThroughputWindows 2000 vs. Windows 2003
0
1000
2000
3000
4000
5000
6000
7000
2CPU 4CPU 8CPU
Pa
ge
s/se
c
J2EE Application Server A J2EE Application Server B .NET 1.0/W2K .NET 1.1/Windows.NET
91%91%
34%34%
70%70%
http://www.middleware-company.com/documents/j2eedotnetbenchmark.pdf
ASP.NET Benchmarks
Baseline: ASP.NET is 3x faster than Active Server Pages
ASP.NET + OutputCaching: 3x faster than baseline
ASP.NET + OutputCaching + IIS 6.0: 6x faster than baseline
Credit: Rob Howard, http://www.gotdotnet.com/team/rhoward/
Design for Performance
Have GoalsBusiness process metrics
Runtime performance
Understand the platformFramework
O/S
Application architectures
Juval’s rule: 10x
Measuring Performance
GetTickCount APIMilliseconds since system startup
System.DateTime
Highest ResolutionQueryPerformanceCounter API
Returns frequency per second
Returns current time value
Analyzing Performance
PerformanceCounter classWork with existing system countersCreate application specific counters
.NET-provided countersInteropExceptionsJITLock and threadNetworkingRemotingSecurity
Analyzing Performance3rd Party Profilers
Intel: VTunehttp://developer.intel.com/
NuMega: DevPartner Profilerhttp://www.compuware.com/products/numega/dps/profiler/
Rational Software: Quantifyhttp://www.rational.com/
Plus more…
Examples in Everyday Code
Late Binding
String vs StringBuilder
Boxed Unknowingly
Collections
Binding
ASP.NET Web Server Controls
Cache
JIT Optimization
CPU-specific instructionsCross assembly cache optimization Range check eliminationConstant foldingConstant/copy propagationMethod incliningCode hoistingLoop unrollingDead code removalPlus more…
Generics
Amateur benchmark Push/Pop on stack in tight loop
Type-safe generic value type vs boxed value type
73% faster
Type-safe generic ref-type vs just object 5% faster
Bottom line – use generics
Less known Practices
But just as important Allocation and finalization
Remoting
Security
Transactions
Memory AllocationEvery process has a managed heap
New objects allocated off the heap, and the pointer moves up
When the heap is exhausted, GC takes place
Multi generation allocationNew object part of younger generation
Younger generations are more collectable
Heap is pre-allocatedAllocation is much faster than nativeallocation
Obj 1
Obj 2
Obj 3
Obj 4
New Object
Managed Heap
Garbage Collection
Dispose of unreachable objectsObject that no one can reach no client has a reference to
Nobody can use them OK to kill
.NET keeps list of rootsTop-level objects: static, global, local variable, GC objects
JIT compiler maintains the list
When GC starts, it deems everything as garbage
Garbage Collection
GC traverses recursively from rootsBuilds a graph of reachable objects
Adds to graph just once (cyclic references)
All threads must suspend during GC
Dispose of unreachable objectsTreated as empty space
Moved to finalized queue if required
CompactionMove reachable objects down
Patch references
Obj 1
Obj 2
Obj 3
Obj 4
Obj 8
Obj 10
New Object
Obj 1
Obj 2
Obj 3
Obj 4
Obj 8
Obj 8
Obj 10
Garbage
GarbageCollection
Garbage Collection
New Object
Garbage Collection
Intelligent Cleanup
Generational mark and sweep
Self-Tuning
Limited control in System.GC
GC.CollectForces a full collection
Hurts performance
Impacts tuning algorithm
Garbage Collection GenerationsGen0
New objects, short livedSized based on processor cache10ms collection time
Gen1Middle aged objectsSized based on app allocation rate10ms to 30ms collection time
Gen2The oldest objectsSized based on app allocation rateCollection time is the most expensive
Large ObjectFor objects > 80KbCollected, but not relocatedCollected during Gen2 collections
Garbage Collection Types
Workstation GCHosted by console or Windows forms applications
Can take advantage of MP
Server GCParallel MP Capable
GC Thread per CPU
Multiple Heaps for Scalability
Finalization
Object can optionally implement Finalize() method
void Finalize(){…}
GC knows about Finalize() from Metadata
GC calls Finalize()
Finalization and Destructor
In C#, even if you add a destructor, the compilers converts it to Finalize()
In C#, do not use Finalize(), always use destructor
public class MyClass{ public MyClass(){} ~MyClass(){}} /// code that is actually generated:
public class MyClass{ public MyClass(){} protected virtual void Finalize() {
try { //Your destructor code goes here } finally { base.Finalize();//everybody has one, from Object } }}
Finalization
Finalization postpones releasing resources to undetermined point in the future
Usually till next GC
Can severely hamper application scalability
Use deterministic finalization if an issue
Deterministic Finalization
Unlike COM, there is no way the object knows when is not required by its clients
Unless you implement your own reference count
Object has to be explicitly told by client when not required
Two programming patternsClose/Open
IDisposable
Object implements System.IDisposable interface
public interface IDisposable{ void Dispose();}public interface IMyInterface{ void MyMethod();} public class MyClass : IMyInterface,IDisposable{ public void MyMethod(){} public void Dispose() { //do object cleanup, call base.Dispose() if has one } }
IDisposable
IDisposable
AdvantagesClients are decoupled from finalization mechanism
Disadvantages Makes sharing objects complicated
Couples clients to clients All your base classes should implement Dispose() or IDisposable
Remoting Performance Binary over TCP is comparable to DCOM over RPC
i.e very fast
SOAP is slowerAt least order of magnitude
Performance matter lessProductivity
Extensibility
Interoperability
Scalability
Throughput
Remoting Single Call Object
Key to scalability
Object exist only while call in progress
Dealing with expensive objects and greedy clients
Only accessed when client makes call, not during construction
Cannot have parameterized constructors
Client ProxySingle Call
Object
3 5
Client Proxy
2
Client ProxySingle Call
Object
1
4
1 Object executes call on behalf of a remote client1 Object executes call on behalf of a remote client
2 When call returns, .NET calls 2 When call returns, .NET calls IDisposable.Dispose()IDisposable.Dispose(), then releases , then releases all references, making it a candidate for garbage collectionall references, making it a candidate for garbage collection
3 Client makes another call on the proxy3 Client makes another call on the proxy
4 Proxy forwards call to the remote domain4 Proxy forwards call to the remote domain
5 .NET creates an object, and calls the method on it5 .NET creates an object, and calls the method on it
Single Call ObjectSingle Call Object
public class Param{…} public class MySingleCallComponent : MarshalByRefObject,IDisposable{ public MySingleCallComponent(){…} public void MyMethod(Param objectIdentifier) { GetState(objectIdentifier); DoWork(); SaveState(objectIdentifier); } protected void GetState(Param objectIdentifier){…} protected void DoWork(){…} protected void SaveState(Param objectIdentifier){…} public void Dispose(){…} /* Class members/state */ }
Single Call ObjectSingle Call Object
Cannot have state in memory between callsCannot have state in memory between callsMust be state-aware object Must be state-aware object
Leasing
GC is per process
Who keeps remote objects alive?
Each app domain has lease managerFor exposed remote objects
Each remote object is associated with a lease object
Lease keeps object alive
Lease manager maintains list of leases
Reachable, so not collected
Leasing
Passing object ref outside process creates a lease
Lease is for client activated objects and singletons
Lease has lease timeoutWhen expires, object is garbage
Lease has default timeout: 5 minutes
Client and object can control lease timeout
Lease Interface
Defines lease properties and policy
Lease class implements ILease System.Runtime.Remoting.Lifetime
public interface ILease { TimeSpan CurrentLeaseTime {get;} LeaseState CurrentState {get;} TimeSpan InitialLeaseTime {get;set;} TimeSpan RenewOnCallTime {get;set;} TimeSpan SponsorshipTimeout {get;set;} void Register(ISponsor obj); void Register(ISponsor obj,TimeSpan renewalTime); TimeSpan Renew(TimeSpan renewalTime); void Unregister(ISponsor obj);}
Object-Provided Lease
public class MyServer : MarshalByRefObject{ public override object InitializeLifetimeService()
{ ILease lease = (ILease)base.InitializeLifetimeService(); Debug.Assert(lease.CurrentState == LeaseState.Initial);
//Set lease properties lease.InitialLeaseTime = TimeSpan.FromMinutes(30); lease.RenewOnCallTime = TimeSpan.FromMinutes(10); lease.SponsorshipTimeout = TimeSpan.FromMinutes(2); return lease;
}}
Sponsor is a third party, consulted when lease expires
Given opportunity to renew lease
Sponsor implements ISponsor
A lease can have multiple sponsors Lease manager maintains a list per lease, in ascending order
One or more invoked, given an opportunity to renew lease
Lease Sponsors
public interface ISponsor { TimeSpan Renewal(ILease lease);}
public class MySponsor : MarshalByRefObject,ISponsor { public TimeSpan Renewal(ILease lease) { Debug.Assert(lease.CurrentState == LeaseState.Active); //Renew lease by 5 minutes return TimeSpan.FromMinutes(5); }}
ISponsor sponsor = new MySponsor();
//Create the remote object - after registration MyServer obj = new MyServer();
/Register the sponsorILease lease = (ILease)RemotingServices.GetLifetimeService(obj);lease.Register(sponsor);
Implementing SponsorImplementing Sponsor
Implementing Sponsor
Sponsor should return the initial lease time
public class GenericSponsor : MarshalByRefObject,ISponsor { public TimeSpan Renewal(ILease lease) { Debug.Assert(lease.CurrentState == LeaseState.Active) return lease.InitialLeaseTime; }}
Security and Performance
Framework classes have built-in security demands
Indicate type of operation requested
Indicate security action and time
When assembly tries to perform operationGranted access to resource orSecurity exception
Security and Performance
CLR must verify permission of chain of callers
Not good enough if component has permission but not upstream caller
Verify using stack walk
Resource demand for security permission verification triggers stack walk
If even one caller does not have permission -> security exception
class MyClass{ void SaveString(string str,string fileName) { StreamWriter stream = new StreamWriter(fileName,true);//append stream.WriteLine(str); stream.Close(); } void WriteToFile() { string fileName = @"C:\Temp\MyStrings.txt"; string[] array = new string[9]; array[0] = "Every"; array[1] = "string"; array[2] = "in"; array[3] = "this"; array[4] = "array"; array[5] = "causes"; array[6] = "a"; array[7] = "stack"; array[8] = "walk"; foreach(string str in array) { SaveString(str,fileName); } }}
Security and Performance
Can assert permission, to stop stack walk
Requires assertion permission
void WriteToFile(){ string fileName = @"C:\Temp\MyStrings.txt"; string[] array = {"Now","the","stack","walk","stops","here"}; IStackWalk stackWalker; stackWalker = new FileIOPermission(FileIOPermissionAccess.Write, fileName); stackWalker.Assert(); foreach(string str in array) { SaveString(str,fileName); }}
Transaction and Performance
Throughput more than just performance
Use Enterprise Services Gain in scalability
Voting is possibleSet the static property MyTransactionVote of ContextUtil
ContextUtil.MyTransactionVote = TransactionVote.Commit;
[Transaction]public class MyComponent : ServicedComponent{ public void MyMethod(long objectIdentifier) { try { GetState(objectIdentifier); DoWork(); SaveState(objectIdentifier); ContextUtil.MyTransactionVote = TransactionVote.Commit; } catch { ContextUtil.MyTransactionVote = TransactionVote.Abort; } //Let ES deactivate the object once the method returns ContextUtil.DeactivateOnReturn = true; } //other methods protected void GetState(long objectIdentifier){…} protected void DoWork(){…} protected void SaveState(long objectIdentifier){…}}
Transaction and Performance Transaction and Performance
Transaction and Performance
Voting without exception-handling
[Transaction]public class MyComponent :ServicedComponent{ public void MyMethod(long objectIdentifier) { //Let ES deactivate the object once the method returns //and abort. Can use ContextUtil.SetAbort() as well ContextUtil.DeactivateOnReturn = true; ContextUtil.MyTransactionVote = TransactionVote.Abort; GetState(objectIdentifier); DoWork(); SaveState(objectIdentifier); ContextUtil.MyTransactionVote = TransactionVote.Commit; }}
Transaction and PerformanceTransaction and Performance
Best: useBest: use AutoCompleteAutoComplete method-attributemethod-attribute
Sets done and consistency bits to Sets done and consistency bits to true if the method did not throw an true if the method did not throw an exception, and the consistency bit exception, and the consistency bit to false if it did to false if it did
Deactivates JITA objects Deactivates JITA objects
Transaction and Performance
[Transaction]public class MyComponent : ServicedComponent{ [AutoComplete] public void MyMethod(long objectIdentifier) { GetState(objectIdentifier); DoWork(); SaveState(objectIdentifier); }}
More at TechEd
C# Best Practices DEV312
Distributed Security PracticesDEV354
Building High-Performance Applications with Visual Studio .NET
DEV326
Application and Library VersioningDEV343
Software Legends – VS.NET and C# tips and tricksSWL004
microsoft.public.dotnet.framework.performance“Performance Testing .NET Web Applications”, Microsoft ACE Team, MSPRESGotDotNet - CLR Profiler"Performance Considerations for Run-Time Technologies in the .NET Framework"
http://msdn.microsoft.com/library/en-us/dndotnet/html/dotnetperftechs.asp
"Performance Tips and Tricks in .NET Applications"http://msdn.microsoft.com/library/en-us/dndotnet/html/dotnetperftips.asp
.NET CF Perf WhitePaper on www.microsoftdev.com“CIL Programming: Under the Hood of .NET”, Jason Brock, APress
ResourcesResources
ResourcesResources
Programming .NET components By Juval Lowy, O'Reilly April 2003
www.idesign.net
.NET Master Class3-4 annually
Upcoming events onwww.idesign.net
Community Resources
Community Resourceshttp://www.microsoft.com/communities/default.mspx
Most Valuable Professional (MVP)http://www.mvp.support.microsoft.com/
NewsgroupsConverse online with Microsoft Newsgroups, including Worldwidehttp://www.microsoft.com/communities/newsgroups/default.mspx
User GroupsMeet and learn with your peershttp://www.microsoft.com/communities/usergroups/default.mspx
SOFTWARE LEGENDSOFTWARE LEGENDJuval LowyJuval Lowy
THURSDAY 3rd JULY at 16.15-16.45 hrs
Meet the Author’sMeet the Author’s Book signingBook signing
© 2003 Microsoft Corporation. All rights reserved.© 2003 Microsoft Corporation. All rights reserved.This presentation is for informational purposes only. MICROSOFT MAKES NO WARRANTIES, EXPRESS OR IMPLIED, IN THIS SUMMARY.This presentation is for informational purposes only. MICROSOFT MAKES NO WARRANTIES, EXPRESS OR IMPLIED, IN THIS SUMMARY.