NAVmoble - the pocket-sized ERP
Optimized for Microsoft Dynamics NAV and Windows Mobile powered devices

Wednesday, November 09, 2005

Compact Framework Performance Hints

Performance is a big pain in the CF world. Here comes some
usefull general performance hints when using CF 1.0/2.0.

1. Avoid virtual calls when not needed.
Virtual calls are slower that instance and static calls. CF 1.0 virtual calls are interpreted at runtime due to the working set cost(vtables are not used). This cause about 40% slower performing virtual calls compared to statis and instance calls. Interpreted virtual calls are cached in a fixed length cache. CF 2.0 uses a variable size cache which leads to nearly 100% hit rate. Anyway, avoid using virtual calls if not needed.

2. Avoid properties
Properties are slower than field. It may happen compiler to inline property getters and setters but do not dont trust it. CF 2.0 propose better performance on virtual properties due the upper mentioned changes.

3. Avoid PInvoke.
It is up to ~6 times more expensive than managed instance calls.

4.Override Equals() and GetHashCode()
Built in behavior of Equals() and GetHashCode() uses reflection, which leads to extra performance impact. Create your own optimized implementations.

5. Explicit string intern.
It may help optimizing performance, however do not use it ( and trust the builtin interning mechanism)unless you are not sure that it helps. Intern process may bring extra performance penalties if not used properly

6.Method inlining.
Although, it is not easy to predict if the JIT compiler will inline particular method, it may be beneficial trying to make the method a candidate for inlining:
Method must have:
- 16 bytes of IL or less
- No branching
- No local vars
- No exception handlers
- No 32 nit floating argument ot ret values
- Using of arguments in their declaration order
And do not use debugger:)

7. Enregistration
CF 2.0 introduces enregistration- a process of storing 32 bit sized (locals and arguments) into the CPU registers. This leads to significant performance improvement however you should stick with 32 bit sized variables. Less sized variable may not be as efficient as 32 bit due to additional
conversion issues.

8.Garbage Collection
In general GC is expensive process from a performance point of view.
Try to avoid creation of too mach managed objects - for example try to avoid boxing/unboxing operations, poorly written string manipulations, etc. In order to diagnose GC issues lookup "GC Latency Time" perf. counter in mscoree.stat Cf 2.0 allows runtime perf log emit, which may help to better diagnostic/monitoring solutions.

9.Use ThreadPool
If you have a big number of short living async workers using of ThreadPool will help application to perform better.

10.Parsing DateTime
Use DateTime.ParseExact method to parse DateTime.Otherwise a variety of culture specific conversions will be applied until the right one is found.

11.Some common hints
- Avoid iterators - use indexers
- Pre-resize collections
- Avoid boxzing/unboxing
- Use specialized classes for string operations
- Use typed collections for best performance. Extensive generics
usage may increase JIT pressure, which may cause performance penalties depending on the number of the types/generics defined combinations.

12. Xml
-Use XMLReader and XmlWriter for Xml processing
-Don't use schema parsing unless you must.
-Design shorter documents: strip white spaces,use attributes
-Use Skip(), where possible - it is faster than Read()
-Use factory classes XMLReader/XMLWriter to create a proper optimized reader/writer
-Use XmlReaderSettings and XmlWriterSettings classes to get
better optimized readers/writers
-Avoid Windows codepage encodings - Use UTF8 or ASCII
-Create single XmlSerializer per type and cache it for next use.
XmlSerializer serializier creation is expensive

13. Datasets
-Use typed DataSets
-Avoid DateTime columns - use Ticks instead.
-Avoid storing Datasets as Xml - store schema as well if it may not be avoided.
-Use schema, when DataSet loading is done from Xml
-Map columns as attributes when loading DataSet from Xml

14. Data
- Avoid DataSets
- Use DataReader and Sql Server Ce
- Dispose SqlCeCommand and DataReaders

15.WebServices
-Create single WebService proxy instance and use it during the whole application
life cycle in order to avoid first-hit proxy reflection.
-Avoid sending DataSets across the network
- Use DiffGrams if DataSets usage is required.

17. Avoid reflection
Although reflection may give applications flexibility it is quite resource-hungry feature.
Do not use it if possible.

18. GUI
- Load and cache Forms in background
- Do not populate data on Form.Show(). Do it async
- Use SuspendLayout/Resume Layout, when repositioning controls
- Be carefull, when using events
- Use background processing

Details may be found on .NET Compact Framework Team's Blog

3 comments:

Sriram said...

One thing - use ResultSets over DataSets/DataReaders whenever you can. You get all the typed goodness and good perf

Sriram Krishnan
PM, Visual Studio for Devices
http://blogs.msdn.com/sriram

Anonymous said...

Just want to let you know that EQATEC has released the worlds first .NET compact framework profiler. It is free to use and can be downloaded here: http://www.eqatec.com/tools/profiler

The profiler is very easy to use and it has received fine reviews.

Best regards,

Eigil

Anonymous said...

Don't use SqlCeDataReader, use ResultSet via TableDirect.

If you concatinate more than 4 Strings use StringBuilder instead of "123" + "halfjafdjlkdaskl" + "blablabla" + "\r\n" + "hallo"