220 likes | 371 Views
Writing faster managed code. Claudio Caldato Program Manager CLR Performance Team. Outline. Performance engineering Managed code performance Contrast with native code Garbage collection Features’ cost and Pitfalls Perf problems diagnosis. Performance engineering. Set goals
E N D
Writing faster managed code Claudio Caldato Program Manager CLR Performance Team
Outline • Performance engineering • Managed code performance • Contrast with native code • Garbage collection • Features’ cost and Pitfalls • Perf problems diagnosis
Performance engineering • Set goals • Measure, measure and then measure • Know your platform • Process: • Budget, plan, verify • continuous improvement • Measure, track, refine • automated tests • Build a performance culture • User expectations • Developer attitudes – perf is my feature!
Moving to managed code • Why? Productivity and quality • Do more with less code • Fewer bugs • Clean, modern libraries targeting modern requirements • Better software, sooner • But is performance a problem? • Easier to write programs fast • Easier to write fast programs?
Know Your Garbage Collector • Why? • GC basics • Pause threads; trace reachable objects from roots; compact live objects; recycle dead memory • Self tuning • CLR is a generational mark and sweep GC
Generation 1 Generation 0 Garbage Collection in Action New objects allocated in generation 0 GC: accessible references keep objects alive GC: preserves / compacts referenced objects GC: objects left merged into older generation Once again, new objects allocated in generation 0
Know Your Garbage Collector • GC basics • Pause threads; trace reachable objects from roots; compact live objects; recycle dead memory • Self tuning • Generational GC Heaps • Gen0 – new objects – cache conscious; fast GC • Gen1 – objects survived a GC of gen0 • Gen2 – long lived objects – survived a GC of gen1,2 • Large object heap • Server GC • Optimized for throughput and multi processor scalability
Garbage Collection Pitfalls • Object lifetimes still matter! • Use an efficient “allocation profile” • Short lived objects are cheap (but not free) • Don’t have a “midlife crisis” (avoid gen2 churn) • Review with perfmon counters, CLRProfiler • Common Pitfalls • Keeping refs to “dead” object graphs • Null out object references (where appropriate) • Implicit boxing • Pinning young objects • GC.Collect considered harmful • Finalization ...
Garbage Collection Pitfalls (2)Finalization and the Dispose Pattern • ~C(): non-deterministic clean up. • object unref’d • promote to the next generation • queue finalizer • Costs: retains object graph, finalizer thread • use Dispose Pattern • Implement IDisposable • Call GC.SuppressFinalize • Hold few obj fields • Dispose early, when possible use ‘using’ (C#)
Pitfall: Indiscriminate Code Reuse • Your choices determine your perf • Your architecture, algorithms, ... • Your uses of .NET FX types and methods • No specific advice holds everywhere, so you have to do your homework • Measure, inspect the time and space costs of your platform(s), in your setting
Data Cost • Data locality • Remote, disk, RAM, cache • GC: objects allocated together in time, stay together in space • Data representation • Complex data structures with a lot of pointers is GC cost
Reflection Cost • Fast and Light APIs: • TypeOf, object.GetType, get_Module, get_MemberType, new Token/Handle resolution APIs • Costly APIs: • MemberInfo, MethodInfo, FieldInfo, GetCustomAttribute, InvokeMember, Invoke, get_Name • Only request what you need • minimize the use of GetMembers, GetConstructors, … • Consider using the new Token/Handle resolution APIs
Reflection Cost (2) • Cache members after having retrieved them • For instance cache Member’s handle • Avoid using Type.InvokeMember • Avoid doing case insensitive member lookups • Use BindingsFlags.ExactMatch whenever possible • Use FxCop • Insidious • .NET FX code that uses reflection • Late bound code in VB.NET, JScript.NET • Enforce early binding • Option Explicit OnOption Strict On
P/Invoke, COM Interop Cost • Efficient, but frequent calls add up • Costs also depend on marshaling • Primitive types and arrays of same are cheap • Unicode to ANSI string conversions are not. • Diagnosis • Perfmon: .NET CLR Interop counters (# of marshalling) • Time based profiling • Mitigate interop call costs by batching calls or move the boundary
Deployment considerations • Assemblies • Performance-wise: the fewer, the better! • Use GAC • Avoids repetitive SN signature verification • Use NGEN • Caches pre-JIT’d DLL; code may run slower • Generally reduces startup time, improves code shareability • Try it and measure for yourself
Xml: It is not always the answer • System.Xml.dll is 2MB • Load it only when you need it • Don’t use XML classes for trivial tasks • MyApp.Config.Xml: <MyApp> <MainWindow> <Top>512</Top> <Left>340</Left> </MainWindow> </MyApp>
Analyzing Performance ProblemsCode Inspection • Ildasm – findstr “box” • Debuggers – Module loads, rebasing • FxCop – Static Analyzer
Analyzing Performance ProblemsMeasure It, With Tools • High level diagnostics • Taskmgr, perfmon, vadump, event tracing for Windows (ETW) • Space • CLR Profiler, code profilers, ETW • Time • Code profilers, timing loops, ETW
Improve startup time • Cold startup is typically dominated by disk accesses and warm startup by CPU usage. • Reduce dlls loaded at startup if possible. • Ngen your assemblies. Jitting consumes CPU at startup. • Place strong named assemblies in the GAC. • The application would be doing its own computations. Is the bottleneck here?
Resources • Patterns & Practices: Improving .NET Application Performance and Scalability • [http://msdn.microsoft.com/perf] • .NET framework developer center • Programming Information/performance • Usergroup: • microsoft.public.dotnet.framework.performance • Blogs • RicoM, MaoniS • Claudio’s Quick list
Questions • In the product cycle, when do you start working on performance? • What are the top issues you have to deal with? • Are there good tools to do performance analysis?, what is missing? • Where type of resources do you use to find answers to performance issues? • Comment the following statement: “In managed code it is easier to find and solve performance issues”