Advanced iOS Build Mechanics, Sebastien Pouliot

1,547 views

Published on

Published in: Technology, Business
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,547
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
0
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Advanced iOS Build Mechanics, Sebastien Pouliot

  1. 1. Sébastien PouliotSo!ware DeveloperXamarinsebastien@xamarin.comAdvanced iOS build mechanicsImproving performance andreducing executable size
  2. 2. Why Should You Care?Quicker BuildsSmaller ApplicationsFaster Applications
  3. 3. Prime Directive:Time Everything - Often
  4. 4. Best Default Worse147227196How Much Time? Field Service SampleBuild Time (Debug) Deploy TimeBest Default Worse3716141694916Simulator Devices
  5. 5. Building for the iOS Simulator.dllC#.exe+ =.appaddinmtouch•Resolve•Package•Embed  mono•Deploy?
  6. 6. Simulator vs Emulator• Speed Over Compatibility• Apple Simulator TradeoffsSimpler, less restrictive environment• Xamarin Simulator TradeoffsJust In Time (JIT) compilerMinimize files copying (symlinks)Shared application launcher
  7. 7. Simulator : What to Do?bestdefault 72196 Build TimeDeploy Time• BuildAvoid optimizing PNG files• DeployKeep the simulator running
  8. 8. Simulator : What to Avoid?bestworse 142276 Build TimeDeploy Time• BuildEnabling the linkerDisabling the shared launcher -­‐-­‐nofastsim• DeployUp to 12 seconds to cold start
  9. 9. Simulator : Extra Tips• Prefer Build over Rebuild• Avoid copying filesAccess them from a single locationThe sandbox is not enforced• Use -­‐time  -­‐time to measure your changes
  10. 10. -­‐time  -­‐time
  11. 11. Building for iOS Devices•Resolve•Global  Op8miza8ons•AOT  Compila8on•Na8ve  Compila8on•Na8ve  Linking•Copy  files•Op8mize  PNG•En8tlements•Code  sign•IPA•Symbols  (DWARF)•Stripping  (symbols)•Stripping  (IL)•Packaging•Deployment.dllC#.exe+ =? .app
  12. 12. Building for iOS Devicesaddin mtouch•  Resolve•  Managed  Linking•  AOT  Compila8on•  Na8ve  Compila8on•  Na8ve  Linking•  Symbols  (DWARF)•  Copy  files•  Op8mize  PNG•  Provisioning•  En8tlements•  Code  sign•  IPA•  Stripping•  Registrar•  IL  Removal•  Packaging•  Deploy  apps•  Install  apps.dllC#.exe+ =.app
  13. 13. Devices : Build Configurations• Debug : Keep it quick• Release : Focus on performanceLLVM Optimizing CompilerOptimize PNG files• Ad-Hoc / AppStore : No tweaks!
  14. 14. Build & Deploy Symbiosis• Deployment time is a function of the app size• Application size versus build time?• Link SDK is default for devices
  15. 15. Devices : What to Do?bestdefault 16144916 Build TimeDeploy Time• BuildAvoid optimizing PNG files (debug)• ConsiderLinking all assemblies --linkallDisabling the symbols creation --dsym=false
  16. 16. Devices : What to Avoid?bestworse 371416916 Build TimeDeploy Time• FAT binaries (debug)• Disabling the linker --nolink• Disabling strippingSymbols --nosymbolstripIL (release) --nostrip
  17. 17. Devices : Extra Tips• Prefer Build over RebuildAOT’ed assemblies (object files) are cached• Avoid deploying large static files (debug)Use UIFileSharingEnabled (Info.plist)• Use -­‐time  -­‐time to measure your changes
  18. 18. -­‐time  -­‐time -­‐dsym=false
  19. 19. Beyond Build Tips
  20. 20. It’s a Matter of Time and SizeDon’t LinkLink SDKLink All 91020212389Build Time Deploy Time48.6 MB11.5 MB10.9 MBField  Service  Sample  Applica8on**  Release  build,  LLVM,  ARMv7
  21. 21. 01020304050607080910111213141516Static Analysis Limitations...using  FieldService.Utilities;#if  __iOS__using  MonoTouch.Foundation;  #elif  __ANDROID__using  Android.Runtime;#endifnamespace  FieldService.Data  {        ///  <summary>An  assignment  is  the  "thing"  or  "job"  the  user  is  going...#if  !MOBILE        [Preserve  (AllMembers  =  true)]#endif        public  class  Assignment  {                ...        }
  22. 22. 01020304050607080910111213141516Static Analysis Limitations<!-­‐-­‐  add  `-­‐-­‐xml=field.service.xml`  to  your  project  options  -­‐-­‐><linker>        <assembly  fullname="FieldServiceiOS">                <type  fullname="FieldService.Data.Assignment"  />                <type  fullname="FieldService.Data.AssignmentHistory"  />                <type  fullname="FieldService.Data.AssignmentItem"  />                <type  fullname="FieldService.Data.Document"  />                <type  fullname="FieldService.Data.Expense"  />                <type  fullname="FieldService.Data.ExpensePhoto"  />                <type  fullname="FieldService.Data.Preserve"  />                <type  fullname="FieldService.Data.Labor"  />                <type  fullname="FieldService.Data.Photo"  />                <type  fullname="FieldService.Data.Signature"  />                <type  fullname="FieldService.Data.TimeEntry"  />        </assembly></linker>
  23. 23. Partially Linking Applications• Link All and skip some assembliesNo source requirede.g. -­‐-­‐linkall  -­‐-­‐linkskip=FieldServiceiOS• Link SDK and use [LinkerSafe] attributeSource code required
  24. 24. Objective-C Bindings• Cocos2d’s Jumpy saves 409 KB using[assembly:LinkerSafe]• Less [Export] means faster registration
  25. 25. SmartLink• New option [LinkWith  (SmartLink=true)]and -­‐-­‐registrar=static• Helps the native linkerDropBox’s Sync samples drops by 325KB
  26. 26. 01020304050607080910111213141516[Export  ("sizeToFit")]void  SizeToFit  ();[Export  ("sizeToFit")][CompilerGenerated]public  virtual  void  SizeToFit  (){        global::MonoTouch.UIKit.UIApplication.EnsureUIThread  ();        if  (IsDirectBinding)  {                Messaging.void_objc_msgSend  (this.Handle,                          Selector.GetHandle  ("sizeToFit"));        }  else  {                Messaging.void_objc_msgSendSuper  (this.SuperHandle,                          Selector.GetHandle  ("sizeToFit"));        }}Automatic Bindings Optimizations[Export  ("sizeToFit")]void  SizeToFit  ();[Export  ("sizeToFit")][CompilerGenerated]public  virtual  void  SizeToFit  (){        global::MonoTouch.UIKit.UIApplication.EnsureUIThread  ();        if  (IsDirectBinding)  {                Messaging.void_objc_msgSend  (this.Handle,                          Selector.GetHandle  ("sizeToFit"));        }  else  {                Messaging.void_objc_msgSendSuper  (this.SuperHandle,                          Selector.GetHandle  ("sizeToFit"));        }}
  27. 27. 01020304050607080910111213141516System.Drawing.SizeF  ret;if  (IsDirectBinding)  {        if  (Runtime.Arch  ==  Arch.DEVICE)  {                  Messaging.SizeF_objc_msgSend_stret  (out  ret,  this.Handle,  ...        }  else  {           ret  =  Messaging.SizeF_objc_msgSend  (this.Handle,  ...        }}  else  {        if  (Runtime.Arch  ==  Arch.DEVICE)  {                Messaging.SizeF_objc_msgSendSuper_stret  (out  ret,  ...        }  else  {                ret  =  Messaging.SizeF_objc_msgSendSuper  (this.SuperHandle,  ...        }}return  ret;Automatic Bindings OptimizationsSystem.Drawing.SizeF  ret;if  (IsDirectBinding)  {        if  (Runtime.Arch  ==  Arch.DEVICE)  {                  Messaging.SizeF_objc_msgSend_stret  (out  ret,  this.Handle,  ...        }  else  {           ret  =  Messaging.SizeF_objc_msgSend  (this.Handle,  ...        }}  else  {        if  (Runtime.Arch  ==  Arch.DEVICE)  {                Messaging.SizeF_objc_msgSendSuper_stret  (out  ret,  ...        }  else  {                ret  =  Messaging.SizeF_objc_msgSendSuper  (this.SuperHandle,  ...        }}return  ret;
  28. 28. 01020304050607080910111213141516Automatic Bindings Optimizationsobject  __mt_RootViewController_var;[CompilerGenerated]public  virtual  UIViewController  RootViewController  {     [Export  ("rootViewController",  ArgumentSemantic.Retain)]     get  {         global::MonoTouch.UIKit.UIApplication.EnsureUIThread  ();         UIViewController  ret;         if  (IsDirectBinding)  {           ret  =  (UIViewController)  Runtime.GetNSObject  (...  msgSend  ...);           }  else  {           ret  =  (UIViewController)  Runtime.GetNSObject  (...  msgSendSuper  ...);         }         if  (!IsNewRefcountEnabled  ())           __mt_RootViewController_var  =  ret;            return  ret;      }...object  __mt_RootViewController_var;[CompilerGenerated]public  virtual  UIViewController  RootViewController  {     [Export  ("rootViewController",  ArgumentSemantic.Retain)]     get  {         global::MonoTouch.UIKit.UIApplication.EnsureUIThread  ();         UIViewController  ret;         if  (IsDirectBinding)  {           ret  =  (UIViewController)  Runtime.GetNSObject  (...  msgSend  ...);           }  else  {           ret  =  (UIViewController)  Runtime.GetNSObject  (...  msgSendSuper  ...);         }         if  (!IsNewRefcountEnabled  ())           __mt_RootViewController_var  =  ret;            return  ret;      }...object  __mt_RootViewController_var;[CompilerGenerated]public  virtual  UIViewController  RootViewController  {     [Export  ("rootViewController",  ArgumentSemantic.Retain)]     get  {         global::MonoTouch.UIKit.UIApplication.EnsureUIThread  ();         UIViewController  ret;         if  (IsDirectBinding)  {           ret  =  (UIViewController)  Runtime.GetNSObject  (...  msgSend  ...);           }  else  {           ret  =  (UIViewController)  Runtime.GetNSObject  (...  msgSendSuper  ...);         }         if  (!IsNewRefcountEnabled  ())           __mt_RootViewController_var  =  ret;            return  ret;      }...
  29. 29. Quicker buildsSmaller appsFaster apps
  30. 30. Q&A
  31. 31. THANK YOUrelated links @ http://bit.ly/ios-build

×