[swift-users] Static linking

David Beck swift at tnku.co
Mon Jun 20 10:06:24 CDT 2016

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.

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%)
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%)

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%)
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

> On Jun 18, 2016, at 8:41 AM, David Beck <swift at 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>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20160620/bcbd174d/attachment.html>

More information about the swift-users mailing list