iOS app launch time measurement

We used DYLD_PRINT_STATISTICS to measure our app’s pre-main() launch times

enter image description here


There is a possibility to get process start time with C api:

#import <sys/sysctl.h>

static CFTimeInterval processStartTime() {
    size_t len = 4;
    int mib[len];
    struct kinfo_proc kp;

    sysctlnametomib("kern.proc.pid", mib, &len);
    mib[3] = getpid();
    len = sizeof(kp);
    sysctl(mib, 4, &kp, &len, NULL, 0);

    struct timeval startTime = kp.kp_proc.p_un.__p_starttime;
    return startTime.tv_sec + startTime.tv_usec / 1e6;
}

In swift you will have something like this:

private static func processStartTime() -> TimeInterval {
    var kinfo = kinfo_proc()
    var size = MemoryLayout<kinfo_proc>.stride
    var mib: [Int32] = [CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()]
    sysctl(&mib, u_int(mib.count), &kinfo, &size, nil, 0)
    let startTime = kinfo.kp_proc.p_starttime
    return TimeInterval(startTime.tv_sec) + TimeInterval(startTime.tv_usec) / 1e6
}

After that you can calculate startup time with the different ways.

For example I do:

let currentTime = CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970
let startupTime = currentTime - processStartTime()

Full post about that I found here


You can go to edit scheme on Xcode and add a environment variable (DYLD_PRINT_STATISTICS = 1) as shown in the image enter image description here

When you run the app the details will be printed on debugger output as below:

Total pre-main time: 481.88 milliseconds (100.0%)
         dylib loading time:  71.70 milliseconds (14.8%)
        rebase/binding time:  53.66 milliseconds (11.1%)
            ObjC setup time:  40.04 milliseconds (8.3%)
           initializer time: 316.33 milliseconds (65.6%)
           slowest intializers :
             libSystem.B.dylib :  16.71 milliseconds (3.4%)

Please watch the video for more details.