debug环境下打印启动耗时环境变量设置
EditSchema -> Run -> Arguments -> Environment Variables
添加
DYLD_PRINT_STATISTICS
和DYLD_PRINT_STATISTICS_DETAILS
值均为1
其中DYLD_PRINT_STATISTICS
打印信息如下:
Total pre-main time: 203.41 milliseconds (100.0%)
dylib loading time: 164.62 milliseconds (80.9%)
rebase/binding time: 126687488.9 seconds (48910103.9%)
ObjC setup time: 12.02 milliseconds (5.9%)
initializer time: 56.09 milliseconds (27.5%)
slowest intializers :
libSystem.B.dylib : 2.42 milliseconds (1.1%)
libBacktraceRecording.dylib : 4.68 milliseconds (2.3%)
libMainThreadChecker.dylib : 33.34 milliseconds (16.3%)
ShadowDemo : 11.59 milliseconds (5.7%)
DYLD_PRINT_STATISTICS_DETAILS
输出如下:
total time: 8.1 seconds (100.0%)
total images loaded: 358 (351 from dyld shared cache)
total segments mapped: 21, into 383 pages
total images loading time: 7.8 seconds (95.4%)
total load time in ObjC: 12.02 milliseconds (0.1%)
total debugger pause time: 7.6 seconds (93.4%)
total dtrace DOF registration time: 0.00 milliseconds (0.0%)
total rebase fixups: 45,504
total rebase fixups time: 6.99 milliseconds (0.0%)
total binding fixups: 533,200
total binding fixups time: 296.49 milliseconds (3.6%)
total weak binding fixups time: 0.93 milliseconds (0.0%)
total redo shared cached bindings time: 333.74 milliseconds (4.0%)
total bindings lazily fixed up: 0 of 0
total time in initializers and ObjC +load: 56.09 milliseconds (0.6%)
libSystem.B.dylib : 2.42 milliseconds (0.0%)
libMainThreadChecker.dylib : 33.34 milliseconds (0.4%)
ShadowDemo : 11.59 milliseconds (0.1%)
total symbol trie searches: 1243688
total symbol table binary searches: 0
total images defining weak symbols: 37
total images using weak symbols: 92
开发阶段只具备参考意义,并不能准确反映线上的情况。
获取进程创建的时间
#import <sys/sysctl.h>
#import <mach/mach.h>
static CFAbsoluteTime __startProcessTime = 0.f; // 进程创建时间
void processStartTime() {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
struct kinfo_proc kProcInfo;
int cmd[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, [[NSProcessInfo processInfo] processIdentifier]};
size_t size = sizeof(kProcInfo);
__startProcessTime = 0.f;
if (sysctl(cmd, sizeof(cmd)/sizeof(*cmd), &kProcInfo, &size, NULL, 0) == 0) {
NSUInteger startTime = kProcInfo.kp_proc.p_un.__p_starttime.tv_sec * 1000.0 + kProcInfo.kp_proc.p_un.__p_starttime.tv_usec / 1000.0;
/// 处理成相对于2001/01/01 00:00:00的绝对时间戳,以便与CFAbsoluteTimeGetCurrent()时间戳相对应
NSCalendar * calendar = [NSCalendar currentCalendar];
calendar.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
NSDate *date = [calendar dateWithEra:1 year:2001 month:1 day:1 hour:0 minute:0 second:0 nanosecond:0];
NSTimeInterval interval = [date timeIntervalSince1970];
__startProcessTime = startTime - interval * 1000;
}
});
}
其他方案,诸如将某个+load
的调用时间作为启动的时间点,或者注入一个动态库,在动态库中某个时机记录一个时间作为起始时间都不够精确。