iOS启动优化之Static linking vs Dyld 3

Static linking

我们在iOS启动优化之从exec()到main()这篇文章中介绍过,动态链接器在搜索依赖项时进行大量的计算和磁盘IO。

静态链接消除了所有dylib搜索的需要-依赖和可执行文件成为一体。

因此,可以将一些库静态地链接到主可执行文件中,减少framework的数量,从而达到优化应用程序启动时间的目的。

那么如何将framework编译为静态库呢?

在Xcode9中,可以通过Build Settings中的MACH_O_TYPE = staticlib来设置,当设置该标志时,链接器会生成静态库。至于通过cocoapods集成的库,我们必须在podfile中创建一个自定义脚本,以便仅在pod安装期间(即依赖项安装期间)为选定的外部库设置此标志,因为cocoapods在每次重新安装时都会为托管库创建新的工程结构。

如果想在Xcode9之前执行静态链接,可以使用libtool

除了动态库,framework中还可能包含资源(图像、nib等)。我们去掉了动态库,但是不能留下只包含资源的framework。资源包(bundle)是苹果生态系统中包装资源的一种标准方式,可以通过脚本,将framework中的所有资源输出到*.bundle中。然后,通过代码让应用程序能自动使用正确的资源位置。

下面我们来看下,经过静态链接处理之后,启动时间有什么变化?

下面这张图显示了在不同设备上,将26个dylibs进行静态链接处理之后,启动时间的变化。

可以看到在iPhone 5C上的启动时间减少约2秒。在iPad 2上,启动时间得到了更大的改善——相差约4.5秒。

注意:如果有多个静态链接库,注意不要将其与多个动态库链接-这将导致静态库对象在不同的动态库中重复,这可能是一个严重的问题。

Dyld 3

在 iOS 13 之前,所有的第三方 App 都是通过 Dyld 2 来启动 App 的,其加载过程在iOS启动优化之从exec()到main()这篇文章中也介绍过,这里就不在赘述。

Dyld 2加载过程中,会进行大量的计算和I/O操作,因此,会导致 App 启动时间加长。所以苹果开发团队为了加快启动速度,在 WWDC2017上正式提出了 Dyld 3。

Dyld 3 被分为了三个组件:

  • 一个进程外的 MachO 解析器。
    • 预先处理了所有可能影响启动速度的 search path、@rpaths 和环境变量。
    • 然后分析 Mach-O 的 Header 和依赖,并完成了所有符号查找的工作。
    • 最后将这些结果创建成了一个启动闭包。
    • 这是一个普通的 daemon 进程,可以使用通常的测试架构。
  • 一个进程内的引擎,用来运行启动闭包。
    • 这部分在进程中处理。
    • 验证启动闭包的安全性,然后映射到 dylib 之中,再跳转到 main 函数。
    • 不需要解析 Mach-O 的 Header 和依赖,也不需要符号查找。
  • 一个启动闭包缓存服务。
    • 系统 App 的启动闭包被构建在一个 Shared Cache 中, 我们甚至不需要打开一个单独的文件。
    • 对于第三方的 App,我们会在 App 安装或者升级的时候构建这个启动闭包。
    • 在 iOS、tvOS、watchOS中,这这一切都是 App 启动之前完成的。在 macOS 上,由于有 Side Load App,进程内引擎会在首次启动的时候启动一个 daemon 进程,之后就可以使用启动闭包启动了。

Dyld 3 把很多耗时的查找、计算和 I/O 操作都预先处理好了,使得启动速度有了很大的提升。

通过测试,Dyld 2 和 Dyld 3启动时间的对比:

launch typeDyld 2Dyld3
warm0.722s0.731s
cold3.687s2.947s

可以看出,在冷启动时Dyld3 比 Dyld2快20%

Static linking VS Dyld 3

测试结果如下:

launch typeDyld3static
warm0.731s0.679s
cold2.947s2.276s

通过测试结果,我们可以看出,使用静态链接的 App 总是比使用Dyld 3 的 App 启动的更快。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值