This morning I used the DYLD_PRINT_STATISTICS environment variable that was 
recommended in the session (I couldn’t get it to work on an iOS device, so 
these are numbers from the simulator). “Cold” refers to launching the app after 
a restart to make sure that the libraries aren’t already in memory and “hot” is 
when the app has been run recently. I created 2 basic iOS projects, one Swift 
and the other ObjC, using the empty view template, and changing nothing except 
the environment variable. I ran this experiment a few times over for all 4 
scenarios, and these are typical results.

Swift:
Cold:
Total pre-main time: 140.49 milliseconds (100.0%)
         dylib loading time:  49.29 milliseconds (35.0%)
        rebase/binding time:  15.57 milliseconds (11.0%)
            ObjC setup time:  50.73 milliseconds (36.1%)
           initializer time:  24.72 milliseconds (17.5%)
           slowest intializers :
               libSystem.dylib :   7.22 milliseconds (5.1%)
   libBacktraceRecording.dylib :   8.49 milliseconds (6.0%)
                CoreFoundation :   3.41 milliseconds (2.4%)
                    Foundation :   4.42 milliseconds (3.1%)
Hot:
Total pre-main time:  63.33 milliseconds (100.0%)
         dylib loading time:  27.78 milliseconds (43.8%)
        rebase/binding time:  11.38 milliseconds (17.9%)
            ObjC setup time:  13.25 milliseconds (20.9%)
           initializer time:  10.83 milliseconds (17.1%)
           slowest intializers :
               libSystem.dylib :   2.46 milliseconds (3.8%)
   libBacktraceRecording.dylib :   4.84 milliseconds (7.6%)
                    Foundation :   1.52 milliseconds (2.4%)

ObjC:
Cold:
Total pre-main time: 133.77 milliseconds (100.0%)
         dylib loading time:  43.62 milliseconds (32.6%)
        rebase/binding time:  14.08 milliseconds (10.5%)
            ObjC setup time:  51.98 milliseconds (38.8%)
           initializer time:  23.88 milliseconds (17.8%)
           slowest intializers :
               libSystem.dylib :   6.52 milliseconds (4.8%)
   libBacktraceRecording.dylib :   7.93 milliseconds (5.9%)
                CoreFoundation :   3.89 milliseconds (2.9%)
                    Foundation :   4.32 milliseconds (3.2%)
Hot:
Total pre-main time:  55.55 milliseconds (100.0%)
         dylib loading time:  21.90 milliseconds (39.4%)
        rebase/binding time:  11.30 milliseconds (20.3%)
            ObjC setup time:  12.92 milliseconds (23.2%)
           initializer time:   9.34 milliseconds (16.8%)
           slowest intializers :
               libSystem.dylib :   2.98 milliseconds (5.3%)
   libBacktraceRecording.dylib :   3.52 milliseconds (6.3%)
                CoreFoundation :   1.23 milliseconds (2.2%)
                    Foundation :   1.15 milliseconds (2.0%)

Keep in mind that the recommended startup time is 400ms. The Swift standard 
libraries never show up in slowest initializers, but something does seem to be 
slowing the Swift startup time down at least a little, but not by a significant 
amount. My conclusion would be that the Swift libs are indeed optimized and 
shouldn’t be a major concern.

However, my bigger concern was in an app that has 3rd party dependencies (like 
my own). I’m looking at a 700ms pre-main time, with all my Carthage 
dependencies showing up in the slowest initializers list. While some of them 
could be refactored out, others are either non-simple, or for a service we use 
such as analytics. I’m curious how we can optimize the launch time of a Swift 
app that uses 3rd party frameworks, since iOS doesn’t support static linking of 
Swift code.

Interestingly, Crashlytics uses a framework, with a module map, that can be 
used by Swift code directly, but the binary is a static lib that doesn’t need 
to be embedded. I wonder how they created that...

David Beck
http://davidbeck.co
http://twitter.com/davbeck
http://facebook.com/davbeck

> On Jun 18, 2016, at 8:41 AM, David Beck <sw...@tnku.co> wrote:
> 
> In session 406: optimizing app startup time at WWDC, most of the 
> recommendations were very pro Swift. Things like using structs and the fact 
> that it can automatically inline calls. One recommendation that was very anti 
> swift, was the section on limiting dylibs. The presenter recommended keeping 
> it to under 6. I’m not sure if the 15 libswift dylibs that get included by 
> default in a Swift application count towards that (he did mention that Apple 
> frameworks are optimized, but I’m not sure if that is limited to the ones 
> preinstalled on the device).
> 
> His recommendation was to use static libraries, which makes sense, except 
> that Swift on iOS doesn’t seem to support static linking. But for whatever 
> reason, Swift PM ONLY supports static linking. Is there any plans to add 
> static linking to Mac and iOS apps? The only alternative I see at this point 
> is to simply include the source files from libraries in the app’s target, but 
> Swift has from the beginning encouraged naming things generically and relying 
> on modules for name spacing.
> 
> David Beck
> http://davidbeck.co <http://davidbeck.co/>
> http://twitter.com/davbeck <http://twitter.com/davbeck>
> http://facebook.com/davbeck <http://facebook.com/davbeck>

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Reply via email to