您现在的位置: 首页 热点关注 > > 正文
抖音 Swift 编译优化 - 基于自定义 Toolchain 编译提速 60%
发布时间:2023-04-17 11:33:55 来源:字节跳动技术团队

优化方案基于 Swift Toolchain 源码,本文不再探讨 Toolchain 相关基本概念及配置流程等,仅聚焦方案本身。​


【资料图】

背景

随着混编落地的业务场景越来越多,越来越大,开发中出现的性能痛点开始显现,问题很明显集中在被 Swift 环境所依赖的 OC 仓的头文件改动上。因此基建架构把重点放在接口层依赖的性能分析上,力求解决性能瓶颈。

抖音基础技术团队借助自定义 Toolchain 能力,通过自定义编译参数,裁剪 Clang Header 指定内容,最终实现编译提速 60% 。

本方案已于 2022 年 11 月底上线,在抖音稳定运行近 5 个月。下面就让我们一起回顾下整个方案从提出到落地的全过程。

初步分析

在混编场景下,若要确保 OC 与 Swift 间尽可能充分地互操作,则模块化的启用无法仅用在 Swift 编译上下文中——Swift编译导出的 Clang Header,在工程中以​​$(project_name)-Swift.h​​形式出现,将其需要被 re-export 引用的 OC 依赖项,以模块的形式导出,这就意味着若 OC 编译不启用模块化,则无法正确使用 Swift 提供的头文件。

如图,二者不可兼得,Objc Pod D 为了能够解析语句​​@import A;​​而引入​​A.modulemap​​,则其与 A 的互操作不可能再基于文本导入的逻辑,而全面转向模块化。

对于抖音而言,巨型 OC 项目的大量头文件传递依赖的历史包袱,使得在 OC 编译中引入模块化是一场灾难。模块化环境下,缓存系统决议是否要命中 .o 缓存的耗时,比文本环境下重新编译耗时还要长;增量编译时,也会导致广泛的模块重编,改动一个头文件,就要等待数分钟。

传递依赖治理是一项长期工程,但编译优化等不了那么久,我们需要一个可以快速解决的方案。

优化效果

在介绍方案之前,先上结论。

在抖音工程中选取代码量最大的 OC&Swift 混编仓库进行测试:

OC 增量编译:选取被 Swift 依赖的 OC 接口层头文件进行改动,编译耗时降低 60%Swift 增量编译:选取被 OC 依赖的 Swift public class 进行改动,编译耗时相近,无变化全量编译:清除本地编译缓存进行 clean build,编译耗时降低 17%

可见该方案对编译速度的巨大提升。接下来就让我们回顾一下整个方案从预研到上线的过程。

方案原理

解决问题的关键在于降低将 OC 头文件预编译耗时,这里有两个思路:

长期:模块解析的耗时根源在于传递依赖,模块的特性导致不同模块内包含的头文件的传递依赖会将模块增量重编的影响范围扩展到很大。业务库在现有工程架构体系下已经严格控制了接口层传递依赖,因此长期方案会逐步推动治理基础库的传递依赖问题。短期:将 OC 头文件预编译转回文本导入,即裁剪-fmodule-map-files注入,但依然保留对 OC 调用 Swift 代码的支持

Swift会将自身接口层(即 public/open )声明使用到的 C/OC 模块,在​​xxx-Swift.h​​中以​​@import aaa​​形式给出,这就要求 OC 侧使用该头文件时也需要将这些模块对 OC 侧可见,我们想要达成目的,就需要对这些声明进行裁剪。这需要自定义工具链的支持。

本次优化方案效果测试针对的是短期方案。

通过修改编译器,对 Swift 编译生成的 Clang Header Interface 进行裁剪,删除掉系统库以外的 @import,而 OC 侧引用该头文件的地方手动补全依赖。即以暂时牺牲接口self-contained为代价,使OC侧不必再关心模块相关的因素。为支持更细粒度的控制,通过向编译器注入编译参数,以针对不同组件控制此功能的启用,以及实现更具体的裁剪内容。

而对于​​-fmodule-map-files​​的裁剪相对容易,只需修改​​OTHER_CFLAGS​​即可关闭​​-fmodule-map-files​​的注入。

预研方案拆解

我们先来对整个方案做一个任务拆解,可以分析出各部分的依赖关系,节省预研阶段的耗时。

一个工具链相关的落地方案,必须保证其稳定性,因此一定是可以通过一种简单的方式进行外部控制开关的。

从发版角度讲,工具链发版并不像业务代码,和存放在开发仓库的配置一样可以灵活发版,因此应尽可能保证工具链代码的稳定,非必要不修改。

基于这两个原则,我们可以拆解为:

1.分析 ​​swiftc​​ 的参数解析机制,在编译时的参数列表中拼接新的自定义参数以控制裁剪能力。​​swiftc​​ 是实际的前端 ​​swift-frontend​​ 的一个入口,下面会详细提到,向 swiftc 注入的参数列表,在各 ​​swift-frontend​​ 子任务中并不总是以相同的全集出现,作用机制需要进一步分析。

2.基于细粒度控制的考量,参数选择传入一个配置文件,包含一个白名单,来确定哪些​​@import Module​​是可以留下的。我们也有考虑过黑名单,但实际工程的依赖情况是复杂的,不论是 Cocoapods 还是 seer ,都仅能描述工程层面的依赖情况,而不能保证实际编译时的依赖情况,难以构建一个全面的业务黑名单。而系统库白名单是相对固定的,并不需要经常维护。

3.寻找生成 -Swift.h 的具体函数,以及写入​​@import Module;​​的逻辑以进行裁剪。

4.在写入逻辑处加载白名单文件并进行过滤。

5.通过本地验证,完成无感知下发 Toolchain 的验证,打出测试 Toolchain 。

6.灰度验证。

7.合码发版上线。

快速验证

想要验证方向是否正确,同时给予饱受编译耗时困扰的业务同学以信心,需要先找到最关键的点快速验证。

因此我们决定先直接整体关掉所有 -Swift.h 的​​@import Module;​​生成逻辑。此时我们对整体 Swift 源码的认知还较为模糊,但我们只需要去寻找类似​​<< "@import"​​或其他写文件的逻辑再去筛选即可,所幸这一过程没有花费太久。

我们很快找到了这块逻辑,并直接将​​out << "@import " << Name.str() << ";\n";​​注释掉,打包验证成功,出具了本文开头的数据报告,给业务同学吃下一颗定心丸。

接下来,我们就可以稳健地按部就班地去执行其他任务了。

开发、调试swift-frontend 参数解析流程

于是我们将目光转向了其他在前端层级应用的原生参数,并参考它们的写法。很快我们将目光锁定在​​module-cache-path​​,这是一个 Swift 前端编译必需的参数,指定模块缓存位置,且后面传入一个路径,完全符合我们的要求。

根据对该参数的分析,可得 -frontend 阶段的参数解析流程,具体调研过程不再展开,直接简单过下流程。

简单流程如上图,下面具体过下修改参数解析流程的代码位置。

定义

此处使用了一种十分类似 python 的,LLVM 推出的 TableGen(https://llvm.org/docs/TableGen/)语言,后面这些 flag ,我们需要的是

FrontendOption 前端参数,拥有这个flag才会进入前端参数解析流程,而 Clang Header 生成的过程就发生在前端流程中ArgumentIsPath 参数为路径,告知编译器该参数后携带路径字符串作为参数

仿照这种形式的自定义参数:

第二个 EQ 定义其实是一种 Alias,定义了可以使用" flag=arg "这种形式来进行传参,没有其他额外作用。

通过​​tablegen​​工具,把 Options.td 的内容生成为 Options.inc ,如下图

结合 Swift 源码中 Options.h 的 OPTION 定义,引入并提供给 cpp 代码使用

解析

解析过程发生在 CompilerInvOCation 的参数解析流程中

在 ArgsToFrontendOptionsConverter 方法中,从参数列表读取需要的信息,赋值到 Opts 当中

Opts 是一个 FrontOptions 类型的实例,我们需要在这里定义一个字符串以存储我们需要的参数

Opts 会在整个前端流程中流转,为各环节提供必要参数。

Clang Header 生成流程

调用过程的流程图如下,PrintAsClang 是一个相对独立的模块,我们改动只需要关注这两个标红环节即可。

增加入参定义

在原方法定义上加入两个传参,分别是我们传入的白名单文件路径,以及诊断信息,诊断信息后面会提到,用于提示一些自定义错误。

这里也是相同,增加两个参数定义。

白名单解析

printAsClangHeader 这里是我们的主要修改之一,在这个 function_ref 当中,我们对 allow list path 指向的文件进行了内容解析,得到白名单指定的模块名称,以参数形式传递给下一个环节。

writeImports 方法在原有基础上增加一个 function_ref,可以理解为 ​​lambda​​ 表达式,就是我们刚刚做的白名单解析的过程。

在具体写入​​@import Module;​​处进行白名单筛选,在白名单内部的允许写入,否则跳过。

自定义诊断信息

DiagnosticsClangImporter.def 中加入两个自定义条目,error 用于提示解析错误,note 仅提示白名单为空,为空是允许的操作,此时退化为默认逻辑。

前面我们在方法定义中传入了 Diags 实例,想要提示信息,只需简单调用即可,note 只会输出到日志,error 则会打断编译流程。

验证、上线

可使用云构建机器打出测试 Toolchain,下载至本地,集成到 Xcode 中在抖音验证即可。

将自定义参数加入到指定混编组件的编译参数当中,即可成功构建。

后记

Swift 工具链定制是一个拥有无限可能的方向,包括编译优化这类效率提升的工作等等,都可以在底层进行传统意义上的架构层所难以进行的深度优化,后续针对这块可做的事还有很多,相信有更多的经验可以分享给到大家。

标签:

新兴食品现身市场 “植物肉”产品能否“俘获”消费者的胃?

最近一段时间,部分超市和电商平台售卖的植物肉纷纷推出促销优惠活动,销量看涨。不过也有消费者表示,...

绍兴招才引智云对话活动举行 诚邀天下英才“会盟”绍兴

懂人才是大学问,聚人才是大本事,用人才是大智慧。近年来,绍兴市大力实施人才强市战略,持续深化人才...

江苏省自然资源厅出台指导意见 推进老旧小区改造工作

省自然资源厅近日出台《关于大力推进城镇老旧小区改造工作的指导意见》,针对城镇老旧小区改造中规划和...

2021年中国心血管健康指数排名:江苏位列前五

进行了排名,江苏位列前五。北京、上海、江苏等地居民心血管更健康这项发表在《中国疾病预防控制中心周...

科研人员揭示5种豆科植物的核型数据及亲缘关系

近日,四川农业大学林学院副教授罗小梅团队在遗传学领域期刊《基因》(Genes),在线发表了题为《基于5S ...

“烟火气”十足的“江苏味道” 河西CBD顶流商圈开街迎客

开街啦!5月18日上午,在河西CBD金融城融媒路上,2022江苏省新能源汽车&信息消费创新产品推广系列活动启...

首个锌金属的伴侣蛋白诞生 有助于解决缺锌公共卫生问题

据17日发表在《细胞》与《细胞报告》杂志上的两篇论文,美国研究人员发现了第一个锌金属的伴侣蛋白,并...

科学家首次揭示糖尿病卵母细胞起源 有助于减少生育缺陷

5月19日,记者从浙江大学获悉,浙大医学院附属妇产科医院黄荷凤院士团队与中国科学院徐国良院士团队合作...

前4月河北省电信网络诈骗案件发案数连续4个月同比下降

记者从省政府新闻办5月18日举行的河北省打击治理电信网络诈骗犯罪工作新闻发布会上获悉,今年1至4月,全...

重庆:到2025年25个重点领域企业能效全部达到基准水平

3月18日,重庆日报记者从市发展改革委获悉,日前,市发展改革委、市经济信息委、市生态环境局、市市场监...

重磅!2021“发现重庆之美”获奖名单揭晓

3月19日,2021发现重庆之美颁奖典礼在线上举行,最美城市管理人、最美坡坎崖、最美街头绿地、垃圾分类时...

去年重庆回收废弃农膜1.4万吨 农膜回收率达89.31%

3月16日,市五届人大常委会第六十九次主任会议听取了市政府关于《重庆市人大常委会对市人民政府农业面源...

申报分两批!今年国家级博士后科研工作站新设站工作启动

3月19日,重庆日报记者从市人力社保局获悉,为推动产学研深度融合,加强博士后工作平台建设,我市将开展...

浙江鄞州:“水、电、气、数”通办专窗实现城乡公共服务均等化

近日,在宁波市鄞州区邱隘镇公共事务服务中心,66岁的邱隘镇沈家新村居民邱秀月在一个窗口相继办理了不...

打开“浙里办” 浙江1000家农贸市场农产品可线上比价

今天哪个菜场的五花肉最便宜?食品安全抽检结果怎么样?这些问题,浙江居民只需打开浙里办APP上的浙里市场...

浙江鉴湖国家湿地公园规划发布 打造乡村数字旅游

19日上午,鉴湖国家湿地公园规划发布暨东鉴湖农旅观光体验启动仪式在绍兴市越城区陶堰街道举行。当天,...

总投资超10亿元!6个石化装备运维项目在岱山签约

日前,总投资超10亿元的6个石化装备运维项目在岱山经济开发区集中签约。此次签约的项目占地106亩,规划...

如何避免成为“买而不做”的“装备党”祝 杰

自恋是人的天性,人们总是希望自己是更好的,那么自己拥有的事物,也就相应地被自我赋予了更高的价值,...

山西临汾:率先在全省建起农村集体经济开发区

3月17日,临汾市农村集体经济发展(集团)有限公司在临汾经济开发区揭牌。以此为标志,临汾率先在全省建起...

一线工作近22年的缉毒警:我知道坏的是毒品不是人性

  “影子”般的缉毒警:一线工作22年,我知道坏的是毒品不是人性  如果我不继续干,别人也要干,缉...

广东肇庆“毒驾连撞5车致1死”肇事司机被批捕

  1月5日14时30分许,广东肇庆市端州区一男子赵某毒驾连撞5车,致一人死亡。  1月10日,澎湃新闻(ww...

江西最大文物倒卖案宣判:倒卖国家二级文物 9人获刑

  中新网南昌1月10日电 (冷峥嵘 张一怡)江西省共青城市人民法院10日发布消息称,近日,该院依法审结...

青海保障门源地震后生活必需品应急物资

  中新网西宁1月10日电 (记者 孙睿)记者10日从青海省商务厅获悉,青海海北州门源县6 9级地震灾害发...

广西东兴口岸恢复通关 入境需网上预约

  中新社防城港1月10日电 (翟李强)自2022年1月10日零时起,广西东兴口岸和边民互市贸易区恢复人员、...

呼和浩特:寒假期间有条件的学校要开展校内托管服务

  中新网呼和浩特1月10日电 (记者 张林虎)10日,记者从呼和浩特市教育局获悉,在暑假校内托管试点的...

“中国最后一个原始部落”翁丁老寨火灾原因公布

北京市十五届人大五次会议胜利闭幕

天津市委市政府致全市父老乡亲的慰问信:我们一定能够打赢

天津米面油存量由20天提高至30天 超市菜市场进货量翻倍

兰州名师话“美育”:“尚乐立人”分层培优 以“美”润教

子夜直击,天津寒天战“疫”

重庆姐弟被生父扔下坠亡案上诉期结束 一审法院暂未收到两被告人上诉状

天津:划定封控区 全市开展全员核酸检测

江歌母亲江秋莲:尊重法院判决,法律认定在我意料之中

中国边疆“北方第一所”:9名民警守护“生命禁区”

辟谣!网传“封控区管控区相继解封”通知并非西安

河南安阳9日12时至24时新增11例本土确诊病例

老人5折环卫工8折生活困难免费 这家面馆背后有个暖心事

铁路公安以110幅优秀书画作品庆祝人民警察节

本周中东部冷空气频繁 东北等地有降雪

河南新增本土确诊病例60例

“打拐”民警眼里的百态人生:见证一份份不愿放弃的爱

迎腊八北京晴天上线 阵风6至7级体感冻人

多省份倡议春节“非必要不离开”,这地补贴1000元

伪造国家机关证件典型案例发布 有力打击制假贩假行为

15年照顾170多个新生儿 金牌月嫂“漂”到海外去看娃

江歌母亲江秋莲诉刘鑫案一审将于今日宣判

河南省安阳市两地划为高风险地区 一地划为中风险地区

员工迟到一次罚一千引争议 单位惩戒员工法律边界何在?

以体育人 秀出“青年范儿”

保安、厨师曾被竞业限制 企业滥用竞业限制让员工很苦恼

反诈老陈破圈:人民群众在哪 就把反诈宣传开展到哪

一所中职学校的育人实践

各地严惩恶意欠薪 保障农民工及时拿到工资

中学生成剧本杀行业潜在消费人群 多方助推行业“净化”

“这就是我最好的选择”

对餐饮浪费说“不”(百姓关注)

校园“直通车” 服务“零距离”

琉璃河遗址 两段铭文共证北京三千年建城史

千元修复个人征信报告?银行:“征信修复”都是骗局

琉璃河遗址 两段铭文共证北京三千年建城史

北京公交将开展无人驾驶道路测试

河南郑州调整五地为中风险区域 公路入郑需核酸检测阴性证明

“共享法庭”让金融消费者畅享“智慧司法”便利

《传奇2》网游著作权纠纷案峰回路转 最高法五份裁决四份改判一份发回重审

三代警察:从未放弃的28年

“胡叔叔”的寻亲工作室

天津津南本轮本土疫情第3—20例阳性感染者活动轨迹公布

“团圆”行动刑侦专家吕游 每一个案例都有单独的技术方案

河南“战疫”直面五重考验

开考古书店日均两三个顾客 流量时代她决心仍是只卖书

冬奥开幕在即 “双减”催热冰雪课堂

“不得以任何借口拒收患者”彰显生命至上

天津多站进京车票暂停发售

冷空气来袭广州气温骤降 广东多地发布寒冷预警

x 广告
x 广告

Copyright ©  2015-2022 起点自然网版权所有  备案号:皖ICP备2022009963号-12   联系邮箱: 39 60 29 14 2@qq.com