460 likes | 950 Vues
NET Compact Framework 2.0: Optimizing for Performance. Douglas Boling President Boling Consulting Inc. www.bolingconsulting.com. Agenda. General Concepts Starting up The garbage collector Measuring Performance Tips and Techniques. Performance… . …Is important!
E N D
NET Compact Framework 2.0: Optimizing for Performance Douglas Boling President Boling Consulting Inc. www.bolingconsulting.com
Agenda • General Concepts • Starting up • The garbage collector • Measuring Performance • Tips and Techniques
Performance… • …Is important! • This code isn’t on the desktop • Mobile devices are used in real world situations • Time looking at the display is time not looking elsewhere • Bad performance can be dangerous to the user • Embedded devices tend toward time critical jobs • Every task is real time for some measurement of time
General Performance Concepts • Design in performance • Don’t wait until beta to think about performance • Set performance goals • Less code is faster code • Fewer objects are better for performance • Don’t create garbage • Recycle and re-use expensive resources • “Perceived” performance is performance • Use threads and async calls • Initialize lazily • Understand what the APIs are doing
The Key • Know the .NET Compact Framework • The different versions • How it loads applications • How it JITs code • How it manages objects • How it integrates with the underlying operating system
Know the .Net Compact FrameworkThe Different Versions • Compact Framework 1.0 • Three service packs • Significant performance improvements for SP2 • Bug fixes in SP3 • Compact Framework 2.0 • Significant performance improvements (yet again!) • SP 1 in beta
Performance Improvements Bigger #is better Smaller #is better
Know the .Net Compact FrameworkApplication Startup • Start time is important for first impression • Security checks add time to startup • Windows Mobile 5 and Smartphone 2003 perform hash check of all executable files • .Net Compact Framework performs hash check to verify strong name • Keep .exe small, don’t use a strong name on it • For example: avoid embedded resources
Know the .Net Compact FrameworkForm Loading • Performance is ‘perceived’ performance • Preload form classes • Do this asynchronously if loading large amounts of data
Example: Split Off Big Jobs public partial class frmAbout : Form { public frmAbout() { InitializeComponent(); ThreadPool.QueueUserWorkItem( new WaitCallback(_loadAboutImage)); } void _loadAboutImage(object dummy) { string path = …; Image img = new Bitmap(Path.Combine(path, “yourbitmaphere.bmp")); BeginInvoke(new WaitCallback(_setImage), new object[] { img }); } }
Know the .Net Compact FrameworkThe just-in-time compiler (“JIT”) • Designed to be fast and portable, not to generate optimal code • May pitch JIT-compiled code to conserve memory • Out of memory • WM_HIBERNATE • When application goes to background • WM_ACTIVATE • No NGen, install time or persisted code
JITted Code Cost Model • Cost model for method calls • Instance call: ~2-3x the cost of a native function call • Virtual call: ~1.4x the cost of a managed instance call • Platform invoke: ~5x the cost of a managed instance call (marshaling an int parameter) • Watch for hidden method calls • Properties are calls • foreach generates virtual method calls on collection • for faster than foreach
Tips and TricksMath • 32-bit integers: similar to native • 64-bit integers: 5-10x slower • Only use registers for 32-bit values • Floating point: similar to native for ARM • ARM processors do not have FPU
Tips and TricksCollections • Pre-size, resizing creates garbage and copies • foreach has virtual method call overhead, use indexer in tight loops if possible callvirt instance class IEnumerator::GetEnumerator() ... callvirt instance object IEnumerator::get_Current() ... callvirt instance bool IEnumerator::MoveNext() • Collections are usually performance sensitive • Test and tweak for optimal performance • Many options: custom collections (for example, based on strongly-typed array), Generic collections, built-in collections, etc.
Exceptions • Exceptions are cheap…until you throw • Only throw exceptions in exceptional circumstances • Do not use exceptions for control flow • Use performance counters to track the number of exceptions thrown • Replace “On Error/Goto” with “Try/Catch/Finally” in Microsoft Visual Basic®.NET
Tips and TricksInterop • Keep in mind the cost of P/Invoke (~5x managed invoke) • Make “chunky” calls, not “chatty” ones • COM Interop VTable calls use P/Invoke path • Avoid IDispatch if possible (~5x slower than VTable) • Watch out for complex marshalling • Value types are “blittable”, marshaled quickly • Complex types, including many COM types (e.g. VARIANT, BSTR, SAFEARRAY) are slower • Use [in] [out] attributes to eliminate unnecessary marshalling
Tips and TricksData • DataSet.ReadXml—use a schema! • SQL readers/writers are much faster than XML • Use Visual Studio designers and typed data sets • Use SqlCeResultSet http://blogs.msdn.com/sriram/archive/2005/11/12/492070.aspx • Use DataGrid binding, especially for large DataSets
Tips and TricksData and Web services • DataSets over Web services is okay in moderation • Send changes only: DataSet.GetChanges() (New in v2) • May require extra work to ensure both sides are in sync • In some cases, it may be better to define your own message format to send data
Easiest to program and maintain Least overhead, fastest Tips and TricksNetworking 101 • Understand the cost of sending data • Time: more layers = more work • Efficiency: more layers = more metadata Web Services and XML HTTP Sockets
Tips and TricksNetworking • For most applications, managed sockets should be fast enough and not the limiting factor http://blogs.msdn.com/mikezintel/archive/2005/03/30/403941.aspx • Do not use synchronous network calls in the GUI thread • Avoid automatically retrying network requests in case of failure • User will generally know if a retry is appropriate; retries can make application appear sluggish http://blogs.msdn.com/oldnewthing/archive/2005/11/07/489807.aspx
Reflection • Reflection can be expensive • Performance cost • Type comparisons (typeof())—inexpensive • Member access (Type.InvokeMember())— think10-100x slower • Working set cost • Member enumerations (Type.GetFields())—expensive • Runtime data structures: ~100 bytes/type, ~80 bytes/method • Be aware of APIs that use reflection as a side effect • Override Object.ToString() • Override GetHashCode() and Equals() for value types
Reflection behind the Scenes • Pay reflection cost once • Persist objects that use reflection • Web services • Reflect over proxy code when service is created • Reflect over method parameters on first call • XML serializers • Reflect over type when serializer created • Use GetValue/SetValue to query and populate object • Consider custom serialization if performance critical
Know the .Net Compact FrameworkThe Garbage Collector (GC) • What triggers a GC? • Memory allocation failure • 1M GC objects allocated • Application going to the background • GC.Collect (try to avoid!)http://blogs.msdn.com/scottholden/archive/2004/12/28/339733.aspx • What happens at GC time? • Freezes all managed threads • Finds all reachable objects and marks them • Unmarked objects are freed and added to finalizer queue • GC pools may be compacted • Memory is returned to OS
GC Cost Model • GC only impacts performance when it runs • Prevent it from running too often: don’t create garbage • Test and tune to achieve best balance • Some features have side effects that can create a lot of garbage • String manipulations • Boxing value types • Use performance counters to monitor the GC
Where does garbage come from? • Unnecessary string copies • Strings are immutable • String manipulations (Concat(), etc.) cause copies • Use StringBuilder String result = ""; for (int i=0; i<10000; i++) { result += ".NET Compact Framework"; result += " Rocks!"; } StringBuilder result = new StringBuilder(); for (int i=0; i<10000; i++) { result.Append(".NET Compact Framework"); result.Append(" Rocks!"); }
Where does garbage come from? • Unnecessary boxing • Value types are allocated on the stack (fast to allocate) • Boxing causes a heap allocation and copy • Use strongly typed arrays and collections • Non-generic collections are not strongly typed class Hashtable { struct bucket { Object key; Object val; } bucket[] buckets; public Objectthis[Object key] { get; set; } }
GC Cost ModelSample code: value types and boxing 546 ms Boxed value types 200005Managed objs allocated 200729Garbage Collections (GC) 3Bytes Collected By GC 4132GC Latency Time 155 ms 22 ms Boxed value types 5Managed objs allocated 726Garbage Collections (GC) 0Bytes Collected By GC 0GC Latency Time 0 ms ArrayList a1 = new ArrayList(100000); ArrayList a2 = new ArrayList(100000); for (int i = 0; i < 100000; i++){ a1.Add(i * i); } for (int i = 0; i < 100000; i++){ int j = (int)a1[i]; a2.Add(j); } int[] ht = new int[100000]; int[] al = new int[100000]; for (int i = 0; i < 100000; i++){ ht[i] = i * i; } for (int i = 0; i < 100000; i++){ int j = ht[i]; al[i] = j; }
Using Generics • Can avoid boxing using generics • Understand the tradeoffs: • Pros • Strongly typed • No unnecessary boxing and type casts • Specialized code is more efficient than shared • Cons • Internal runtime data structures and JIT-compiled code aren’t sharedList<int>, List<string>, List<MyType> • May not be faster: make sure to test and measure
GC Cost ModelSample code: generics 546 ms Boxed value types 200005Managed objs allocated 200729Garbage Collections (GC) 3Bytes Collected By GC 4132GC Latency Time 155 ms 77 ms Boxed value types 5Managed objs allocated 732Garbage Collections (GC) 0Bytes Collected By GC 0GC Latency Time 0 ms ArrayList a1 = new ArrayList(100000); ArrayList a2 = new ArrayList(100000); for (int i = 0; i < 100000; i++){ ht.Add(i * i); } for (int i = 0; i < 100000; i++){ int j = (int)ht[i]; al.Add(j); } List<int> ht = new List<int>(100000); List<int> al = new List<int>(100000); for (int i = 0; i < 100000; i++){ ht.Add(i * i); } for (int i = 0; i < 100000; i++){ int j = ht[i]; al.Add(j); }
FinalizersThe object is dead, long live the object! • Cost: • Non-deterministic cleanup: unmanaged resources may stay around longer than wanted • Extends object lifetime: managed memory is not freed until after finalizer runs • Can saturate finalizer thread if create objects faster than they can be finalized • Only use a finalizer if your object contains an unmanaged resource • Implement the “Dispose” pattern (IDisposable) http://blogs.msdn.com/ricom/archive/2004/05/19/135332.aspx
Sample Code: Finalizer and Dispose class SerialPort : IDisposable { IntPtr SerialPortHandle; public SerialPort(String name) { // P/Invoke to native code to open serial port SerialPortHandle = SerialOpen(name); } ~SerialPort() { // P/Invoke to native code to close serial port SerialClose(SerialPortHandle); } public void Dispose() { // P/Invoke to native code to close serial port SerialClose(SerialPortHandle); GC.SuppressFinalize(this); } }
Know the .Net Compact FrameworkKnow the system • Its still Windows • The message loop is hidden, but it’s there • Don’t spend too much time in an event handler • It’s still Windows CE • Until Windows CE 6, you’re limited to a 32M VM • You may run out of VM space before RAM • Load native DLLs early • Otherwise the managed heap will take the entire VM • Its still a small, low cost device • System Performance is data bound
Tips and TricksWindows Forms • Use BeginUpdate/EndUpdate when available • Use SuspendLayout/ResumeLayout when repositioning controls • Keep event handling code tight • Process costly operations asynchronously • Blocking in event handlers will affect UI responsiveness • Limit the work done when a Form loads
Tips and TricksSystem.IO • When using a StreamReader, use buffers that match the internal buffer of the stream • Be aware of the default sizes of internal buffers • FileStream: 128 bytes • StreamReader, StreamWriter: 1024 • Avoid Stream.Seek • If must use, use small buffers
Tips and TricksKnow the target device • Windows Mobile 5 devices are noticeably slower than earlier systems • Persistent store • Security checks • Test on all expected target devices • And those you don’t expect • Plan for the future • Never assume screen sizes or shapes • Smartphone vs. Pocket PC differences
Tips and TricksMotherhood • Design, design, design. Weed out problems before they happen • Test, test, test. Keep your eye on performance targets • Just because you can doesn’t mean you should! • Tips and tricks are guidelines for better designs and better habits
Tips and TricksMeasuring performance • Use Environment.TickCount to measure • Measure times greater than 1 second • Start from known state • Ensure nothing else is running • Measure multiple times, take average • Run each test in its own AppDomain/Process • Log results at the end • Understand JIT-time versus runtime costs
Measuring Performance • Performance counters • Counters give us insight into performance and memory use • Static: <My App>.stat HKLM\SOFTWARE\Microsoft\.NETCompactFramework\PerfMonitorCounters (DWORD) = 1 • Dynamic: Use NetCFRPM (formerly “TuneIn”) • Performance and working set are closely related
Performance Counters: .stat File counter total last datum n mean min max Total Program Run Time (ms) 55937 - - - - - App Domains Created 18 - - - - - App Domains Unloaded 18 - - - - - Assemblies Loaded 323 - - - - - Classes Loaded 18852 - - - - - Methods Loaded 37353 - - - - - Closed Types Loaded 730 - - - - - Closed Types Loaded per Definition 730 8 385 1 1 8 Open Types Loaded 78 - - - - - Closed Methods Loaded 46 - - - - - Closed Methods Loaded per Definition 46 1 40 1 1 2 Open Methods Loaded 0 - - - - - Threads in Thread Pool - 0 6 1 0 3 Pending Timers - 0 93 0 0 1 Scheduled Timers 46 - - - - - Timers Delayed by Thread Pool Limit 0 - - - - - Work Items Queued 46 - - - - - Uncontested Monitor.Enter Calls 57240 - - - - - Contested Monitor.Enter Calls 0 - - - - - Peak Bytes Allocated (native + managed) 4024363 - - - - - Managed Objects Allocated 1015100 - - - - - Managed Bytes Allocated 37291444 28 1015100 36 8 55588 Managed String Objects Allocated 112108 - - - - - Bytes of String Objects Allocated 4596658 - - - - - Garbage Collections (GC) 33 - - - - - Bytes Collected By GC 25573036 41592 33 774940 41592 1096328 Managed Bytes In Use After GC - 23528 33 259414 23176 924612 Total Bytes In Use After GC - 3091342 33 2954574 1833928 3988607 GC Compactions 17 - - - - - Code Pitchings 6 - - - - - Calls to GC.Collect 0 - - - - - GC Latency Time (ms) 279 16 33 8 0 31 Pinned Objects 156 - - - - - Objects Moved by Compactor 73760 - - - - - Objects Not Moved by Compactor 11811 - - - - - Objects Finalized 6383 - - - - - Boxed Value Types 350829 - - - - - Process Heap - 1626 430814 511970 952 962130 Short Term Heap - 0 178228 718 0 21532 JIT Heap - 0 88135 357796 0 651663 App Domain Heap - 0 741720 647240 0 833370 GC Heap - 0 376 855105 0 2097152 Native Bytes Jitted 7202214 152 26910 267 80 5448 Methods Jitted 26910 - - - - - Bytes Pitched 1673873 0 7047 237 0 5448 Peak Bytes Allocated (native + managed) JIT Heap App Domain Heap GC Heap Garbage Collections (GC) GC Latency Time (ms) Boxed Value Types Managed String Objects Allocated
Remote Performance MonitorFormally “TuneIn” • Supported in .NET CF 2.0 SP1 • Beta available now • Dynamically uploads performance data • Counters give us insight into performance and memory use • Counters can be exported to PerfMon
Summary • Make performance a design requirement and measure • Understanding .Net Compact Framework guides good design • Watch memory usage • Understand APIs and side effects • Develop good design and programming habits with tips and tricks
http://blogs.msdn.com/netcfteam/archive/2005/05/04/414820.aspxhttp://blogs.msdn.com/netcfteam/archive/2005/05/04/414820.aspx http://blogs.msdn.com/mikezintel/archive/2004/12/08/278153.aspx http://blogs.msdn.com/davidklinems/archive/2005/12/09/502125.aspx http://blogs.msdn.com/romanbat/archive/2005/01/06/348114.aspx http://blogs.msdn.com/mikezintel/archive/2005/03/30/403941.aspx .NET Compact Framework version 2.0 Performance and Working Set FAQ .NET Compact Framework Advanced Memory Management Monitoring Application Performance on the .NET Compact Framework Generics in the .NET Compact Framework .NET Compact Framework Network Performance http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnnetcomp/html/netcfperf.asp Developing Well Performing .NET Compact Framework Applications Resources
Resources Stop by the MED Content Publishing Team Station in the Microsoft Pavilion or visit the MED Content Publishing Team Wiki site:http://msdn.microsoft.com/mobility/wiki Need developer resources on this subject?
© 2006 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries. The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.