So if you're trying to make your app launch faster, there are a few things you'll want to pay attention to.
What to Measure
When you're looking at startup time, you'll want to measure the time up until the moment after -applicationDidFinishLaunchingWithOptions: is called.
To the system, your app has completed its launch when the first CATranscation has been created and passed off to the render server. This happens right after -applicationDidFinishLaunchingWithOptions: which is why that's when you can stop measuring.
Pre-Main Launch Time
Before main() is even called, your app has to do a bit of setup.
- Dylib loading: First things first, the system needs to load any dynamic libraries, including system libraries like UIKit. You can speed this up by combining dylibs or switching to static libs.
- Rebase Binding: This can be longer or shorter depending on the number of classes in your app.
- Obj-C Setup: At this point the system will take all your Objective-C classes and create the method dispatch tables needed to actually call methods.
- Initializers: This happens when you implement +load methods in Obj-C or Swift.
Swift vs. Obj-C
One interesting thing is comparing two, very simple, identical sample apps. One was written in ObjC and one was re-written in Swift.
First, the ObjC version:
Here we see a total pre-main time of 78.27 ms and a dylib load time of just 11.46 ms.
And then, the Swift one:
Here we have a dylib load time of 256.83ms! This is with no external dylibs being pulled into either app, which means merely using Swift and dynamically linking its standard library is ~25X slower than using Objective-C. This is pretty strange given Apple's recommendation that your pre-main time stay under 400ms when they're taking over half of that off the top just to use Swift.