280 likes | 411 Vues
C# High Performance Mobile Apps. Laurent Testud. Mobile Platforms vs. PC. CPU: 20% ( 32 bits ) GPU: 10% ( Open GL ES 2.0 – DX 9 ) Storage: 150% ( On PCB SSD ) Network: 5% ( Often less, lost connections ). High Perf ’ Apps. Harry’s Lap Timer
E N D
C#High Performance Mobile Apps Laurent Testud
Mobile Platforms vs. PC • CPU: 20% ( 32 bits ) • GPU: 10% ( Open GL ES 2.0 – DX 9 ) • Storage: 150% ( On PCB SSD ) • Network: 5% ( Often less, lost connections )
High Perf’ Apps • Harry’s Lap Timer http://www.youtube.com/watch?v=FWxT7EaBv-E • “Angry Birds” and all interactive Games • “Garage Band” and all Music apps • “Hydrogen!” and most Visualization apps
In High Perf’ Apps… • About 90% of code is NOT time critical Business as usual… • Only 10% is Real Time Must complete within 15ms Requires special attention!
“Classic” Reactive Approach • Iterate: • Design • Code • Debug / Test • Build • When about to ship: • Profile => Hot Spots!!! Blame the summer intern! • Fix • Ship it!
Sadly… Does not work • Profiling: No obvious Hot Spots • instead: Thousands of Hot Spots • Or worse: Hot Spots within Framework • Large memory footprint • Garbage Collection Issues • Memory Warnings
“Proactive” Approach • All dev’ on Low End device (no simulator) • Work on Release Builds (as often as possible) • Monitor performance (fps) • React instantly to Any performance drop • Know your Enemies! Continuous Real Time
First Steps – Design / Think • Review Data Structures • Review Algorithms • Move stuff (as much as you can!) outside the loop • Review API’s usage (low level is usually better)
First Steps - Instrument • Use LLVM Compiler ( iOSXamarin ) • Instrument your ( critical ) code ( low impact ) • Permanently Measure
Code Frugally * • Use the lower level API when applicable • Avoid big and fat third party libraries • Do not over engineer! • Keep it simple! • Code only what you need * : Simple, plain, costing little.
Code for 32 bits • Careful with the Math namespace • Must avoid double and long public static unsafe float InvSqrt ( float x ) { float xhalf = 0.5f * x ;inti = *(int*) & x ; i = 0x5f3759d5 - ( i >> 1 ) ; x = * ( float * ) & i; x = x * ( 1.5f - xhalf * x * x ) ; return x;}
Code Smaller • Go unsafe if needed. • Precalculate as floats: Sin Cos Pow… • Use tables instead • Precalculate as floats: Random numbers • Save bandwidth: Use byte, sbyte, short • Don’t ship debug code • Validators • ToString overrides
Code Simpler • Avoid trivial properties, use fields • Use readonly whenever applicable • Avoid inheritance and virtual • No unnecessary interfaces definitions • Avoid Linq, anon’s, async, tasks
Code to Help * • Use local variables to cache properties • Pass ‘big’ value types by ref • Mark your classes as sealed • Use internal as your default instead of public * : The Compiler
Code Greener! You Shall Not Create Garbage! Garbage needs to be collected. Garbage needs to be recycled. And that can kill you app…
Where does your Garbage comes from? • Enumerators - usually via foreach and Linq • Extreme example • Three nested foreachrunning on 200 items • 200 + 200 x 200 = 40100 enumerator objects • 60 x 8 x 40 K = 19200 K 20 Mega Bytes of Garbage / Second!
Where does your Garbage comes from? • Enumerators - usually via foreach and Linq • Avoid Linq • Iterate using indexing • Use arrays when applicable/needed • Use unsafe pointers if needed: t [ i ] == * ( t + i )
Where does your Garbage comes from? • Objects created for temporary use • Typically ‘Containers’, EventArgs, … • Often Nodes (LinkedList, etc…) • Simplify internal APIs • Simplify data transfers • Pool and Recycle container objects
Where does your Garbage comes from? • Anonymous methods (with capture) • Queued delegates (with parameters) • Regain control of captured variables • Give a name to these animals
Where does your Garbage comes from? • Objects you created for “convenience” • Remember: new is worse than goto • Just don’t. • Recycle • Consider: Promote as class members
Where does your Garbage comes from? • Boxed value types • Improper string manipulation • Growing List<T> and other collections • Avoid boxing • No + on string • No extension methods on value types • Always assign initial capacity to data structures
Where does your Garbage comes from? • “Sloppy” third party libraries • Most not designed for Real Time use • Do too much • Roll your own stuff!
GC.Collect ( ) ? Go for it! • Always outside the loop • Before starting your real time loop • And after ending it. • After disposing, unloading: levels, etc… • GC.Collect ( ) often
Conclusions • unsafe C# equivalent to C or C++ • Compiled C# is FAST on iOS(Thanks Xamarin!) • No need for Objective-C or C++ C# can be used for Real Time apps • Adopt proper approach to performance • Code tight • Be careful with the GC
Thanks! Questions?