iOS启动耗时分析

        启动耗时分析,一般我们会以main函数作为分割点,main之前和main之后main之前称为per-main 阶段。这个由dyld给你反馈应用的耗时。main之后由开发者自己检测。我们可以从main开始打点,到第一个页面显示为止。

通过实际的调试,我们得到各个函数的调用顺序如下:

启动页

main()

UIApplicationMain()

willFinishLaunchingWithOptions()

didFinishLaunchingWithOptions()

loadView()

viewDidLoad()

applicationDidBecomeActive()

启动页是在main()函数调用之前出来的,main()是程序的入口,里面调用了UIApplicationMain()。当App从didFinishLaunchingWithOptions()返回的时候,实际的UI立刻开始加载,但是在applicationDidBecomeActive()这个回调完成之前,UI即使已经初始化,但仍旧被阻塞着。

总的启动时间T包括main()调用之前的pre-main timeT0,

加上从main()到applicationDidBecomeActive()的时间T1。

pre-main阶段耗时

 main函数之前的检测苹果提供了支持,具体配置方式如图

----首先进入Edit Scheme

----然后配置的 key 为:DYLD_PRINT_STATISTICS

----然后我们再运行项目,该项目 pre-main 的耗时就会在控制台输出。

各阶段耗时分析

dylib loading time 动态库载入耗时

载入动态库,这个过程中,会去装载app使用的动态库,而动态库之间有它自己的依赖关系,所以会消耗时间去查找和读取。

优化建议: 

1.系统的动态库,做了优化。所以从效率的角度来说,尽可能使用系统库;

2.而对于开发者定义导入的动态库(dynamically linked shared library),则需要在花费更多的时间。Apple官方建议尽量少的使用自定义的动态库,或者考虑合并多个动态库,其中一个建议是当大于6个的时候,则需要考虑合并它们;

3.在性能上出发将动态库编译成静态库也会优化这部分时间;

rebase/binding time 修正符号和绑定符号耗时

Rebase:在镜像(MachO文件)内部调整指针的指向,针对mach-o在加载到内存中不是固定的首地址(ASLR)这一现象做数据修正的过程。

iOS4.3后引入了 ASLR ,MachO会被加载到随机地址,这个随机的地址跟代码和数据指向的旧地址会有偏差。dyld 需要修正这个偏差,做法就是将 dylib 内部的指针地址都加上这个偏移量。

binding:将指针指向镜像(MachO文件)外部的内容,binding就是将这个二进制调用的外部符号进行绑定的过程。

优化建议:

1.核心思想是在进行动态库的重定位和绑定(Rebase/binding)过程中减少指针修正;

2.减少Objective-C类数量,减少分类,减少实例变量和函数(删除不用的类以及冗余代码,再深一点就是减少第三方工具的使用,可以查看源码,自己实现);

3.减少C++虚函数;

4.多使用Swift结构体(推荐使用swift)

ObjC setup time OC类注册的耗时

主要做以下几件事来完成Objc Setup:

1、读取二进制文件的 DATA 段内容,找到与 objc 相关的信息

2、注册 Objc 类,ObjC Runtime 需要维护一张映射类名与类的全局表。当加载一个 MachO 时,它定义的所有的类都需要被注册到这个全局表中;

3、读取 protocol 以及 category 的信息,把category的定义插入方法列表 (category registration),

优化建议:

1.不刻意的去减少几个类,但是可以避免浪费;

2 随着项目的不断迭代,很多模块和方法已经被废弃但是却一直留存在项目中,导致项目越来越臃肿;

3.我们可以使用一些工具来查找项目中没有被用到的文件。从而达到优化;

initializer time 其他初始化,如上图,细分为其他的几个部分

1、Objc的+load()函数

2、C++的构造函数属性函数 形如attribute((constructor)) void DoSomeInitializationWork()

优化建议: 

1.我们能做的就是将不必须在+load方法中做的事情延迟到+initialize中;

2.这是因为+load方法是在app启动的时候就被调用,而+initialize方法则是在Class第一次使用的时候才调用,相当于是懒加载了。可以把+load中的代码移到initialize中,并结合dispatch_once来防止重复调用;

3.但是我们项目中只有在使用method swizzling的时候会在+load中调用方法。所以这一点也没什么好优化的;

pre-main阶段耗时总结:

1. 动态库加载越多,启动越慢

2. ObjC类,方法越多,启动越慢

3. ObjC的+load越多,启动越慢

4. C的constructor函数越多,启动越慢

5. C++静态对象越多,启动越慢

main()到applicationDidBecomeActive()的阶段耗时

我们可以使用Xcode自带工具Instruments里面的Time Profiler来获取,也可以在main()的第一句和applicationDidBecomeActive()的最后一句加上获取时间的代码CFAbsoluteTimeGetCurrent(),

Time Profiler

工具通过Xcode工具栏中Product->Profile(command+i)可以启动,(也可以通过Xcode->Open Developer Tool->Instruments)启动后界面如下:

选择Time Profiler,打开后如图:

点击左上角红色按钮运行,勾选左下角Call Tree中Separate Thread和Hide System Libraries,等到第一个页面显示出来的之后,点击左上角暂停按钮,下面就会统计出每个步骤的耗时情况。这个时候我们就可以很容易得到启动时间T1。

针对这块时间的耗时优化总结:

我们通过Time Profiler拿到每个步骤的耗时之后,右下角的 Heaviest Trace 可查看比较消耗CPU的代码,双击点击进去可查看到对应的代码,进行修改。有些操作可以延后执行,或者异步执行等,这些需要根据自己的业务逻辑在处理。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,393评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,790评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,391评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,703评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,613评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,003评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,507评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,158评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,300评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,256评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,274评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,984评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,569评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,662评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,899评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,268评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,840评论 2 339

推荐阅读更多精彩内容

  • 转载自腾讯云 App启动过程 解析Info.plist加载相关信息,例如如闪屏沙箱建立、权限检查 Mach-O加载...
    乂滥好人阅读 959评论 0 0
  • 多作者合集,非商业行为,为自己学习巩固。特此声明 启动APP的时候就会花费较长的时间,用户体验很不好。所以针对AP...
    红色海_阅读 687评论 0 2
  • 一款 App 的启动速度,不单单是用户体验的事情,往往还决定了它能否获取更多的用户。这就好像陌生人第一次碰面,第一...
    vicentwyh阅读 1,380评论 0 10
  • 黑色的海岛上悬着一轮又大又圆的明月,毫不嫌弃地把温柔的月色照在这寸草不生的小岛上。一个少年白衣白发,悠闲自如地倚坐...
    小水Vivian阅读 3,090评论 1 5
  • 渐变的面目拼图要我怎么拼? 我是疲乏了还是投降了? 不是不允许自己坠落, 我没有滴水不进的保护膜。 就是害怕变得面...
    闷热当乘凉阅读 4,230评论 0 13