布景

在上一篇文章 [Xcode]一种低本钱的link耗时优化 计划中提到了一个优化计划,可是仍然存在一些副作用。在一次编译LLVM模块时发现,LLVM的Target link仅需求1秒左右。所以这篇文章会以LLVM的c-index-test作为规范继续根究link耗时优化空间。

找出差异

先列出几组头条iOS工程的link耗时数据

  • 未优化前,模拟器带lto

[Xcode]一种低本钱的link耗时优化计划(二)

  • 先前的优化,模拟器吞并静态库带lto

[Xcode]一种低本钱的link耗时优化计划(二)

  • c-index-test的link耗时

[Xcode]一种低本钱的link耗时优化计划(二)

第一轮优化后,耗时从56.8秒变成29.9秒。优化后大部分时刻在reslove symbols阶段。而编译c-index-test的reslove symbols阶段仅需求996ms毫秒

c-index-test的参数解析时刻很短,这其间有什么秘密吗?

通过剖析c-index-test的link指令发现。其间关于.a的引证全部是绝对途径。
这样就避免了从library_search_path中去查找对应的libxxx.a文件。然后加快解析速度。
之前的计划 [[Xcode]一种低本钱的link耗时优化计划] 中也提到,这个计划之所以能够加快link时刻也是由于解析参数的时刻变少了。而吞并静态库会带来一些副作用。(虽然影响不大)
可是LLVM这种处理办法更加合理。有了之前的根底搬家起来也很快。注意一点就是避免直接把途径拼接到xcconfig中。而是运用-filelist参数。否则,很有可能会导致参数过长。
优化完了解析参数仅用2.4s(1276 archive files),比之前吞并静态库还要快(188 archive files)。
假定去掉library_search_path还能够再快一点。为了保证兼容性,暂时保留了library_search_path。
关键是,这个计划仅仅是调整了一下输入参数。没效果没有任何影响。所以也没有吞并静态库的副作用。

[Xcode]一种低本钱的link耗时优化计划(二)

剖析reslove symbols阶段

ld64是开源。虽然不是最新版别,但满足用来剖析reslove symbols阶段。准备好代码后通过一番配备后。先用profile调试看看。

[Xcode]一种低本钱的link耗时优化计划(二)

能够看出,不知道那块开了4个进程非常耗时。(而c-index-test是没有这几个线程的)这儿应该是要害。 接着找到reslove symbols阶段的代码 运用log法对reslove symbols子办法进行耗时剖析得出。 由所以调试的原因,时刻仅做参考。只看权重。

[Xcode]一种低本钱的link耗时优化计划(二)

能够看出buildAtomList和linkTimeOptimize占比较高。
其间buildAtomList没有发现什么失常。
通过调试发现,profile中多出的几个线程就是在linkTimeOptimize创建的。

[Xcode]一种低本钱的link耗时优化计划(二)

看一下linkTimeOptimize的代码,假定没有LLVMObjs就直接return。
调试c-index-test发现在这儿是直接return的。
也就是说头条工程中link时由于存在LLVMObjs导致产生了linkTimeOptimized优化。
那么接下来在 _haveLLVMObjs = true的当地剖析一下那些目标会导致这个flag设置成了true。

[Xcode]一种低本钱的link耗时优化计划(二)

效果log显现只需TTShortVideoBusiness这个库会产生问题。 "~/Desktop/Workspace/tt_app_ios/Pods/TTShortVideoBusiness/arch_ios/libTTShortVideoBusiness_Awesome_.a(AWEActionSheetAnimated.o)"

为何TTShortVideoBusiness会敞开linkTimeOptimized

由于组件途径发布二进制时,会运用一个壳工程一同打出release包和debug包。
运用头条的壳工程打release包时会敞开TLO优化。
而我本地设备的TTShortVideoBusiness也是release版别。那么只需运用debug版别就好了。
通过排查是组件途径的消息队伍丢掉了一些数据。从头同步后能够设备到正常的debug版别了。
处理掉linkTimeOptimized后检验一下。

[Xcode]一种低本钱的link耗时优化计划(二)

reslove symbols阶段耗时削减了7秒左右,但跟c-index-test比仍然有12秒左右的距离。
通过排查发现时刻都花在resolveUndefines上面了。

resolveUndefines

这儿就不细说了。暂时还没有什么处理办法。仅列出一些有用的信息。
c-index-test需求解析200个undefine符号。
头条iOS需求在这个阶段解析5000+undefine符号。
在resolveUndefines会一向循环解析直到undefine符号的数量等于0。
所以继续削减link时刻,只能想办法削减undefine符号的数量了。

20200520更新

本来以为这个计划没有副作用。可是仍是有”副作用”的。

在头条的工程中,假定更换了Other_Link_Flags的一些参数次序后,有必定几率会导致sqlite产生问题。在debug发动时会射中secguardSDK的断语。

通过查询发现是这个WCDBOptimizedSQLCipher库引起的,原本应该用-all_load或许-force_load去加载这个库中的一切符号。却只用了-ObjC 和-l”WCDBOptimizedSQLCipher”。效果导致在调整Other_Link_Flags的一些参数次序后,有些符号没有load进来。所以在工作时产生了失常。

同理还有libasr.a也存在这种问题。

关于这种库主张尽早切换成-force_load的办法来加载。

关于App-Infra DevOps 团队

App-Infra DevOps团队作为公司的移动研制中台,致力于优化公司各业务的研制和交给过程中的质量、本钱、安全、功率和体验。到目前为止我们已经有逾越上百个业务接入,1万+人日常运用;平均每天支撑 3000+研制任务顺畅交给;建设了业界抢先且可能是国内最大的构建集群,每天工作20万+次构建任务。

我们等候更多有热心和创造力的同学参加字节跳动,为字节打造业界最抢先,最高效的生产东西。

我们的作业内容主要包含:

  • 供给任务处理,工程处理,开发调试,交给流程支撑的一站式同开发途径。一同供给Native版及Web版,方针成为下一代端云协同的研制根底设备。
  • 客户端 IDE 云化的根究性项目,意图是供给一整套线上编码、调试环境,让用户翻开浏览器就能够进行代码开发,满足不同场景的需求,提高研制功率。

参加我们

北京-高档iOS开发工程师 — 终端技能 job.toutiao.com/s/2YHxkXW

职位描绘

1、担任公司产品的通用技能研制和功用优化,完毕高质量编码和检验作业 2、结构保护,通用东西开发等 3、规划超卓的代码结构,不断迭代重构; 4、前沿技能研讨,承当关键、难点的技能攻坚

职位要求

1、本科及以上学历,计算机、通讯等相关专业 2、具有厚实的编程功底,超卓的规划才干和编程习气 3、熟练掌握Objective-C,C++,了解Swift的优先 4、了解bash/python/ruby/js的优先

上海-高档iOS开发工程师 — 根底技能 job.toutiao.com/s/2YHm8a7

职位描绘

  1. 担任公司客户端产品的通用根底技能研制,完毕高质量编码和检验作业
  2. 通用研制东西开发、通用结构开发等
  3. 规划超卓的代码结构,不断迭代重构
  4. 前沿技能研讨,承当关键、难点的技能攻坚

职位要求

  1. 本科及以上学历,计算机、通讯等相关专业
  2. 具有厚实的编程功底,超卓的规划才干和编程习气
  3. 熟练掌握Objective-C,C++,了解Swift的优先
  4. 了解前后端相关和跨途径技能、了解bash/python/ruby/js等语言和相关结构的优先

杭州-高档iOS开发工程师 — 根底技能 job.toutiao.com/s/2YHdPAE

职位描绘

  1. 担任公司跨途径相关技能研制,完毕高质量编码和检验作业
  2. 担任通用跨端结构及周边东西开发等
  3. 规划超卓的代码结构,不断迭代重构
  4. 前沿技能研讨,承当关键、难点的技能攻坚

职位要求

  1. 本科及以上学历,计算机、通讯等相关专业
  2. 具有厚实的编程功底,超卓的规划才干和编程习气
  3. 熟练掌握Objective-C,C++,了解Swift的优先
  4. 了解前后端相关和跨途径技能,了解bash/python/ruby/js等语言和相关结构的优先