干货 | 携程旅行App iOS工程编译优化实践

生产级机器学习:从模型上线到系统稳定的关键工程实践 机器学习模型部署不是开发终点,而是系统性工程挑战的起点。当模型脱离训练环境进入真实业务流,其行为受特征延迟、服务依赖、数据漂移、资源约束和合规要求等多重因素影响。本文围绕生产环境中最常被忽视的四大核心问题——特征可用性保障、低延迟推理设计、防御性监控与漂移检测、可审计的模型治理——展开深度解析。结合金融风控与电商推荐等高后果场景的真实案例,揭示95%以上的线上故障源于工程疏漏而非算法缺陷。内容涵盖特征fallback语义对齐、eBPF级延迟诊断、KL散度动态基线告警、GitOps驱动的灰度回滚、以及将监管条 阅读详情

作者简介

 

天超,携程资深软件工程师,关注iOS研发,喜欢用脚本语言解决各种难题。

引言

开发效率的提升,是开发者关注的一个永恒的话题。对于iOS而言,编译速度一直是影响iOS开发和集成测试效率关键的一环。

携程旅行App iOS工程编译,经历了从全源码编译到工程组件化,细分Bundle,再到细分Bundle基础上的进一步优化四个阶段。每次的优化改造都是不断结合业务反馈,深入了解xcode编译过程后的成果。

一、背景

简单回顾一下在做Bundle拆分之前的情况,当时整个iOS工程的所有代码都在一起,并未做工程拆分和解耦,编译时全都是源码编译,数百万行代码全部编译完成要将近一个小时。所有的开发人员都在一个工程里开发,如果因为某个人提交的代码有问题(这是常常会发生的),导致编译了很长时间之后才报错,更是耽误时间,严重影响开发效率。对于测试人员来说,每次需要验证一个功能时打包测试都需要至少等待几十分钟,这是极大的资源浪费。

这个时候的Build过程是全源码complie,几千上万个文件都需要编译、链接,效率可想而知。

所以为了提高开发和测试的效率,提高iOS工程的编译速度刻不容缓。


二、优化方案


2.1 工程组件化

第一个优化是把整个工程的编译过程打散,把代码按照业务线拆分成一个个独立的子工程,每个子工程的编译过程都是独立的。每个子工程只需要保证自己工程的源码能够编译成功,对外输出统一的静态库和资源文件包的产物。这个产物我们叫做Bundle。

单个业务工程(Bundle):

App Build:

对于单个业务来说,编译时间大大缩短,整个Build过程变成单工程complie,多工程link,极大减少了Build过程中的complie花费的时间。

这样有两个好处:

1)对于开发人员,每个业务开发只需要把自己这个子工程切为源码引用,把其他非自己模块的子工程全部用静态库依赖,本地编译也只需要编译自己的子工程,可以大大提升本地开发编译速度。

2)对于测试人员,打包过程就变成了把所有已经编译好的子Bundle静态库链接到一个壳工程里,不需要对每个文件进行编译,可以很快的打包测试验证。


2.2 增量编译

在工程组件化之后,在持续集成平台上单个Bundle的打包时间还是过长。因此框架团队开始研究单个Bundle在持续集成平台上增量编译的可能性。

经过调研,最终选定CCache做为解决方案。CCache是一个编译工具,可以将Xcode编译文件缓存起来,从而达到编译提速。

针对本地开发该方案具有优势,但是在结合自研的移动发布平台MCD(Mobile Continuous Delivery)(后面简称【发布平台】)上使用时效果并没有达到预期,主要有两点原因:

1)同一Bundle多分支共存 :App会存在大小版本同时开发的情况,在发布平台中也就会存在不同版本、不同分支的情况。

2)缓存管理不便 :发布平台打包机器通常仅有250G磁盘空间,当面临磁盘压力时,需要灵活的清理策略。

最终框架团队采用了自管理,能做到缓存物理隔离,同时也就省去了环境配置的步骤。

增量编译具体实现:

1)合并有变动的文件

  • 打包任务会根据新的 commitId 下载一份代码副本,不能直接使用该副本,因为代码文件内容没有变动,仅仅是文件属性的变动也会导致 xcodebuild 缓存不生效。因此需要副本和工作区内的源码做diff,仅仅合并内容有变动的文件。

  • 使用 python 的 filecmp 实现合并代码逻辑,并且支持配置 ignore。

  • xcodebuild 指定 -derivedDataPath 设置缓存路径,并将该目录配置到 diff ignore中。

2)提供清除缓存的功能

  • xcodebuild的缓存有时候会出问题,比如修改了c++文件后有时并不会生效,这种需要提供清除缓存的功能,可以由开发自由选择使用。

截止到以上两步,Native已经基本实现了增量编译,但是实际使用还不够。因为打包主要是在集成系统平台上面完成的,集成平台打包有多台机器。

携程旅行App的打包Jenkins采用的是master-slave模式,一个Job下会有多个节点,Job是随机抽取的节点。为了提高增量编译的命中率,必须要让Bundle和节点关联起来。比如:有ABCD四个节点,HotelBundle每次都落到A节点,这样才能保证A节点中HotelBundle的xcodebuild缓存有效,并且代码diff差异最小。

具体实现:

1)保留Jenkins Job的工作区

该步骤是在Jenkins Job的配置中操作,取消勾选下图中的Delete workspace before build starts

2)使用Jenkins插件建立Bundle和节点的关联

基于Jenkins Label Parameter Plugin,并做改造,实现伪随机,以保证关联的节点下线之后,能使用候补节点正常工作。

发布平台前端提供关联配置,业务可以按需选择使用。

通过以上步骤就实现了增量编译,但是该方案针对swift不生效。swift在Release模式采用的全量编译(如下图),做整体优化。不过swift Bundle可以采用上述Bundle拆分的方案。

以某一个编译源码文件197个、资源文件142个的Bundle为例看下效果。

采用增量编译后,Bundle编译耗时由116s降为9s。


2.3 Bundle细分

最初携程旅行App的Bundle都是按照业务来拆分的,比如:酒店就一个Hotel Bundle,在当时编译速度已经不慢了。但是随着业务的发展,单个Bundle中业务代码越来越多,文件越来越多,导致编译又会变慢。这时,可以将单个Bundle按照功能做更细粒度的拆分,比如酒店拆分出了酒店主工程、酒店基础工程。

更细粒度的Bundle拆分还能带来以下其他收益:

  • 加快本地开发编译:某个功能的开发人员只需要将自己这个功能模块切为源码,其他模块全用静态库,提高本地开发编译效率。

  • 为其他独立app提供更细粒度的模块功能支持:我厂的很多独立App都是共用一套框架和基础组件的,按功能模块细粒度的拆分出独立的模块Bundle后,可以使独立app在选择基础组件时按需选择。


2.4 合理设置头文件搜索路径

业务工程往往会大量依赖基础库代码,在本工程编译过程中,也需要查找到引用的基础代码的头文件。

因为代码还是在同一个仓库里,之前的方案是头文件搜索设置还是指向本地的基础框架代码,使用循环搜索的方式。

这样的好处是任何一个头文件的修改,使用方可以马上感知到。

缺点就是头文件没有特意为方便调用进行组织,搜索起来特别费时。

经过统计,Hotel一个文件的编译往往都是秒级别。一整个工程编译下来就是十几分钟。

因此框架团队意识到必须要和第三方库一样,在目前的.a和资源文件之外,提交include目录包含所有会被外部使用的头文件。

同时,考虑到iOS开发向Swift转型的需要,如果在include目录的基础上,还能够提供一份基于include里头文件的module.mapmodule文件。将方便后期业务方向Swift的迁移。

具体方法是:

1)首先框架的Bundle,在工程设置中点击工程的Target→Build Phases→Copy Files点击+,输入.h把需要暴露的头文件都添加上。

这样会在输出产物的Build目录下,多一个include目录,再通过脚本去把这个目录里面的所有文件复制出来,同时生成module.mapmodule。

2)使用的时候,将头文件搜索路径设置到include目录,并且设置为非递归搜索。

验证下来,Hotel工程修改之后的Build时间为7分钟,相比修改之前的19分钟,时间减少了63%。


2.5 建立中央缓存

费雷德里克·布鲁克斯说软件工程领域没有银弹。通过以上优化后,减少了编译时间,提升了开发和集成测试的效率,但这也不是解决编译速度问题的银弹。随着业务的不断使用,又出现了新的问题:Bundle拉取时间过长。

Bundle化方案各个业务的静态库生成都是在发布平台上编译的,业务在本地开发的时候再使用框架的脚本拉取bundle到本地。发布平台上打测试包的时候也是需要拉取所有Bundle。

发布平台打包过程如下:

1)初始化Jenkins工作区,下载代码副本

2)下载Bundle

3)使用xcodebuild生成ipa

4)上传ipa和符号表

5)Job状态回调

整个过程共耗时7分钟,目前携程旅行App iOS最新的版本的上线Bundle将近70个,每个Bundle的静态库支持arm64、x84_64等指令集,所有Bundle加起来有4G大小,即使在内网全量下载耗时也要2~3分钟。

比如酒店某一Bundle:

所有Bundle全量更新一次耗时:

针对这个问题,解决方案是建立中央缓存。

在用户根目录下,建立一个隐藏的目录.iOSBundleRepo,按照Bundle的版本号存储,同一Bundle可存在多个版本。工具下载Bundle时优先判断缓存,未命中时才开始下载并且缓存到repo中。

建立中央缓存还能带来其他好处:在发布平台做预缓存,使用定时任务更新中央缓存,进一步节省下载耗时。

该方案实际上采用的是空间换时间的策略,随着时间推移,将会带来磁盘不足的问题,所以必须要实现清理机制。

针对不同使用场景需要采用不同的缓存清理策略,具体如下:

  • 本地开发:该模式下,开发可以自由选择更新最新Bundle和仅更新配置,缓存使用不频繁。所以将同一Bundle版本个数调低,缓存有效期拉长。

  • 持续集成:发布平台打包较为频繁,缓存使用比较频繁,并且Bundle版本变动较快,所以将同一Bundle个数调高,缓存过期时间设置为一天。

最终,打包耗时由原来的7分钟降为5分钟。


三、存在的问题和思考

软件开发工程没有银弹,大家都是在焦油坑里挣扎。

Bundle的方案节省了编译的时间,提高了开发的效率,方便了持续集成和测试。

为了提高单Bundle编译速度而导出头文件的方案,牺牲了一定的灵活性换来了编译速度的提高。头文件没有了代码中的直接搜索,框架开发人员从共同开发者真正变成了库提供者,这就要求每一次都接口的修改都要及时更新并导出。

任何一个技术方案肯定是在权衡各方面之后做出取舍的结果。框架团队为了提高iOS Build速度,通过自研的方案,做了拆分Bundle,优化头文件搜索路径,增量编译,建立中央缓存等步骤,基本上满足了现有我厂各业务线的日常开发需求。

【推荐阅读】

“携程技术”公众号后台回复“新书”,

可免费获得两本书的试读样章~

《携程架构实践》

京东

当当

《携程人工智能实践》

京东

当当

 “携程技术”公众号

  分享,交流,成长

Gemma 4B在iPhone端侧AI落地实录:离线、低耗、高可用 端侧AI是指在终端设备(如智能手机)本地运行大语言模型的技术路径,其核心原理是通过模型量化(如Q4_K_M)、硬件加速(Apple Neural Engine)与轻量推理框架协同,在不依赖网络的前提下完成语义理解与生成。该技术显著提升隐私安全性与响应实时性,避免云端传输延迟与数据泄露风险,已成为iOS生态中轻量级智能助手的关键支撑。Gemma 4B凭借Apache 2.0商用许可、深度适配的GGUF量化格式及128K上下文支持,成为当前iPhone上平衡性能、功耗与中文能力的成熟选择,适用于会议纪要、文案润 阅读详情

相关推荐

iOS编译速度优化

前言 优化点 一、优化工程配置 二、使用 CocoaPods 管理第三方库:利用 cocoapods 插件 cocoapods-packager 将任意的 pod 打包成 Static Library,省去重复编译的时间;(缺点是不方便调试源码,如果库代码反复修改,需要重新生成二进制并上传到内部服务器) 三、CCache(CCache 是一个能够把编译的中间产物缓存起来的工具,不需要过...

专注于计算机研发知识和资讯分享 2万+

干货 | 携程机票App KMM iOS工程配置实践

作者简介Derek,携程资深研发经理,关注Native技术、跨平台领域。前言KMM(Kotlin Multiplatform Mobile),2022年10月迎来了KMM的beta版,携程机票也是从KMM开始出道的alpha版本就已在探索。本文主要围绕下面几个方面展开说明:如何在KMM项目中配置iOS的依赖KMM工程的CI/CD环境搭建和配置常见的集成问题的解决方法本文适合于对KMM有一定的了解的...

携程技术 2978

优化Xcode编译时间

优化Xcode编译时间

干货 | 携程火车票iOS项目开发体验优化实践

作者简介田东海 ,携程移动开发专家,专注于移动端框架、移动端性能。唐元帅,携程资深软件工程师,致力于平台基建开发。一、背景现在各大公司的APP都采用的是组件化架构,组件化架构带来了高内聚、低耦合、平台化等诸多有点,使工程结构更加清晰,工程管理更加轻松。iOS工程大多采用CocoaPod进行组件化管理,一些大型的项目需要打包平台来执行组件打bundle包和APP打测试包的任务,在开发方面会采用二进制...

携程技术 3050

组件化框架

说到组件化开发,网上可以看到很多资料,如蘑菇街、滴滴、淘宝、携程、豆瓣的组件化架构。但里面介绍比较多的是在现有app如何拆分,组件间如何通信。没有说组件该如何去搭建,像网络请求,json解析这些每个组件都需要用到的共用工具该如何处理。

ios 旅游 APP 携程

ios 旅游 APP 携程

携程旅行移动端代码

html代码 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=dev...

Bubble的博客 2214

OMNeT++入门指南:从tictoc1到tictoc18的实例解析与实战演练

本文是OMNeT++网络仿真框架的入门实战指南,详细解析了从tictoc1到tictoc18的经典示例。内容涵盖OMNeT++的下载安装、核心三文件(.ned, .cc, .ini)的编写、模块化建模、自定义消息、数据统计与可视化,以及参数化批量仿真等核心技能,帮助读者从零开始掌握这一强大的网络仿真工具。

weixin_29228781的博客 329

iOS编译流程以及编译优化原理

iOS编译流程以及编译优化原理

极客洪成的博客 1639

视频倍速 - 在线调倍速的加速器APP工具

一刀工具箱APP提供一键可将手机上的视频倍速播放,可以调整视频倍速的加速器,调节视频的速度也就是调节视频的播放速度!一键可将手机上的视频倍速播放,可以调整视频倍速的加速器,调节视频的速度也就是调节视频的播放速度!视频倍速-在线调倍速的加速器-一刀工具箱APP。...

无涯教程 7558

Python爬虫实战:5分钟搞定东方财富网股票数据抓取(附完整代码)

本文详细介绍了如何利用Python爬虫技术,快速抓取东方财富网的实时股票数据。通过逆向分析其JSONP数据接口,构建了包含请求处理、数据清洗、分页调度及多格式存储的完整自动化采集系统,并提供了应对反爬策略与生产部署的进阶优化思路,附有可直接运行的完整代码。

weixin_29084231的博客 875

[贝聊科技]如何将 iOS 项目的编译速度提高5倍

前言 贝聊目前开发的两款App分别是贝聊家长版和贝聊老师版,最近因为在快速迭代开发新功能,项目规模急速增长,单个端业务代码约23万行,私有库约6万行,第三方库代码约15万行,单个客户端的代码行数约60万。现在打包一次耗时需要11~12分钟。虽然还远远比不上 Facebook 的40分钟,但是我们在内测的时候,经常一天要发布内测版两到三次。打包时CPU占用基本上是百分百的,因为没有专门的 CI 机器...

weixin_34095889的博客 621

YOLOv8剪枝实战:基于torch_pruning的模型优化与性能提升指南

本文详细介绍了如何使用torch_pruning工具对YOLOv8模型进行结构化剪枝,以实现模型轻量化与性能提升。通过实战步骤解析,包括环境搭建、依赖图分析、迭代剪枝与微调策略,帮助开发者有效减少模型参数量和计算量,提升在边缘设备上的推理速度,同时保持检测(detect)与分割(segment)任务的精度。

water的专栏 1122

干货 | 终于来了!携程开源RN开发框架 - CRN

作者简介赵辛贵,携程无线平台研发部开发总监。2013年加入携程,主要负责App基础框架研发相关工作,曾参与Native、Hybrid和ReactNative框架设计、工...

携程技术中心 3169

测绘程序设计——试题一:出租车轨迹数据计算

仅展示试题1的原文,如需了解其余内容,请自行购买图书李老师著作主页-http://ybli.users.sgg.whu.edu.cn/book/

chengzilhc的博客 892

多模态轨迹预测:行人、车辆的交互式推理

多模态轨迹预测:行人、车辆的交互式推理 ,人工智能,计算机视觉,大模型,AI,本文围绕多模态轨迹预测中行人与车辆的交互式推理展开,介绍了其定义,即综合多种信息预测交通参与者未来多种轨迹。涵盖基础概念如轨迹表示、模态、交互关系,技术框架包括数据处理、特征提取、预测模型(物理、机器学习、深度学习模型等)及结果评估。还探讨了交互式推理方法、面临的不确定性处理等挑战、应用场景、未来发展方向、相关工具及实际案例,展现了该技术在智能交通等领域的重要性与发展潜力。​

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 14万+

浏览器端视频摘要工具:3步实现离线、隐私、可交互的结构化提效

视频摘要本质是将非结构化音视频内容转化为可检索、可跳转、可复用的知识单元。其技术原理涵盖元数据解析、语音转文字(ASR)、语义分段与多粒度摘要生成,核心价值在于降低认知负荷、提升信息吸收效率。相比依赖LLM API的云端方案,客户端轻量化处理保障隐私安全与离线可用性,特别适合学生精学课程、运营追踪动态、创作者素材管理等高频场景。本文聚焦基于WebAssembly与TinyBERT的纯前端实现路径,详解YouTube视频的免密钥解析、时间锚点校准及可交互摘要视图构建。

cm333666的博客 514

【2026年华为暑期实习(AI)-4月8日-第一题- 选择题】(题目+思路+Java&C++&Python解析+在线测试)

答案与解析 1. 相关系数问题 答案:C. 完全负线性相关 解析:相关系数ρ=-1表示X和Y之间存在完全负线性相关关系,所有数据点都严格落在一条斜率为负的直线上。 2. 矩阵秩问题 答案:B. Σ的对角线上非零奇异值的个数 解析:矩阵A的秩等于其奇异值矩阵Σ中非零奇异值的个数,因为U和V都是正交矩阵,不改变矩阵的秩。 3. 条件概率问题 答案:B. 0.5 解析:根据全概率公式和贝叶斯公式计算,P(B)=0.5×0.4+0.3×0.6=0.38,P(A|B)=(0.5×0.4)/0.38≈0.526,最接近

m0_73659489的博客 287

幸福里 C 端 iOS 编译优化实践-优化 40% 耗时

动手点关注干货不迷路????背景经过长期的业务迭代,C 端工程增量编译已经严重劣化,2021 年 12 月前,C 端平均增量编译长达 3 分钟以上,严重影响研发效率,急需优化!经过优化之后,增量编译时长降低到 2 分钟左右。分析幸福里 app 编译过程主要耗时分析全量编译:pod 编译占用大部分时间,多达数百秒,CI 打包需要 20 到 30 分钟。增量编译:link、资源处...

字节跳动技术团队官方博客 2049

回归预测 | MATLAB实现TCN时间卷积神经网络多输入单输出回归预测

回归预测 | MATLAB实现TCN时间卷积神经网络多输入单输出回归预测

机器学习之心的博客,关注并私信文章链接,获取对应文章源码和数据。 2492

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

百度APP iOS端包体积50M优化实践(七)编译器优化

本文重点介绍编译器优化,在百度APP实践中,编译器优化包括GCC语言编译优化、Swift编译优化、LTO优化、剥离调试符号、剥离符号表、剔除未引用的代码、Asset 优化、C++虚函数优化和三方SDK编译器方向瘦身。

lihui49的博客 2252

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

iOS性能优化 - 分析&应用

本文主要探讨iOS应用性能优化的关键指标与场景应用。性能指标包括CPU占用率(线程使用、方法耗时、I/O操作优化)、GPU渲染(FPS监测)和内存管理(缓存策略与泄漏检测)。场景应用涵盖启动优化(Pre-main与main阶段策略)、页面渲染(原生与Web页面优化、动画效果)、网络加速(WebP图片、HttpDNS解析)等。此外,还介绍了编译打包优化、包大小缩减以及APP稳定性(闪退与卡顿问题)的解决方案。通过工具检测(Xcode Instruments、第三方组件)和实施优化策略,可有效提升iOS应用的性

风·之痕的博客 8892

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

iOS编译优化终极指南:如何快速提升Swift/Objective-C编译速度

作为一名iOS开发者,你是否曾经历过这样的场景:修改一行代码后,等待编译的时间足够你喝杯咖啡?😅 随着项目规模扩大,编译时间逐渐成为开发效率的瓶颈。本文将为你揭秘iOS编译优化的核心技巧,让你的开发效率大幅提升! ## 📊 编译时间为什么如此重要? 在iOS开发中,编译时间直接影响开发者的工作效率和开发体验。当你的项目达到一定规模时,每次编译可能需要几分钟甚至更长时间。这不仅浪费宝贵的时间

gitblog_00634的博客 1178

iOS之性能优化·提高App的编译速度

一、前言 经过多年的开发和迭代,我相信很多的 iOS 项目代码已经达到几十万行甚至上百万行的规模,所使用的 Pod 库的数量可以达到几十个甚至上百个,App Store 安装包也变得越来越大,在这么大的项目规模下,打包和编译问题逐步成为开发团队一个躲不过的痛,严重影响了研发效率与其他团队之间的协作。 有时间,一台机器同时需要承接七八个项目,多个分支的打包任务,在有多个项目同时打包的情况,尤其显得力不从心。 在硬件资源有限的情况下,并且在无侵入、无影响现有的业务的前提下,如何解决这些成为摆在团队面前的难题和

╰つ栺尖篴夢ゞ 3万+
上一篇: 干货 | 响应速度与智能化如何平衡,携程酒店搜索实践
下一篇: 干货 | 携程桌面应用的前端内存优化与监控
携程技术
博客等级 码龄10年 3716粉丝 324原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值