从分钟到秒:抖音如何通过动态库优化实现高效构建

如果无法正常显示,请先停止浏览器的去广告插件。
分享至:
1. 从分钟到秒:抖 如何通过 动态库优化实现 效构建 :张星宇 程师 字节跳动 / 软件 演讲
2. 录 01 背景 02 动态库的优势与挑战 03 核 04 收益与规划 作流程与原理
3.
4. 01 背景 构建耗时的瓶颈与思考
5. 抖 90% 的构建属于增量构建,其耗时直 接决定研发效率 增量构建代码改动量极 ,缓存命中 率 ,付出的等待时间是否合理 超过 200 时
6. 增量构建的耗时分布 编译 3% 源码到 进制 MachO 的过程 调试启动 13% LLDB 启动调试准备的过程 产物安装 38% App 传输到 机的过程 链接 47% 动态库或可执 件的 成过程
7. 关键阶段耗时统计度量 具链,字节跳动终端技术
8. 耗时的影响因素 改动的代码,以及受这些 参与链接的静态库越多, Xcode 安装时会 改动( 静态库的体积越 的哈希。有改动的 如头 件)影响 的代码越多,速度越慢 ,符号 总数越多,链接速度越慢 多、 件体积越 较 件 件越 ,安装 速度越慢 LLDB 会加载、解析并缓存 动态库或可执 件的原 数据。改动的动态库或可 执 件越 ,调试启动 越慢 编译 链接 产物安装 调试启动
9. 常 成本 ,原 Preview 基于 Swift 的动态能 时替换 中等。稳定性有保障,但是 流程 ,偶尔出问题 动态库 ,适配和改造成本 实现运 不 ,只 持动态库或 SPM 程, 持 cocoapods 静态库。不 持断点。 中等,底层动态库改动会沿着 依赖链路反向传递 中,部分场景会退化为普通编译 低,依赖 ld-prime 链接器, 不可定制 低,依赖 Xcode 内部多个 服务,不可定制
10. 理想中的 程复杂度 关的常数级耗时
11. 02 动态库的优势与挑战 动态库虽好,但使 要注意
12. 动态库的优势 链接 构建系统只需要重新链接动态库,其它部分 LLDB 只加载解析动态库,其它部分 调试启动 Xcode 只需要传输动态库,其它部分 产物安装 改动, 改动, 动态库链接速度快 动态库安装速度快 改动,调试启动速度快
13. 理想中的 程架构 App App 组件 1 Dev.framework 组件 3 组件 4 组件 2 组件 … 组件 1 组件 2 组件 5 组件 6 组件 … 组件 1000 Core.framework 组件 1000
14. 静态库转动态库的问题 静态库 B 组件 A 组件 D 不可少:动态库对完备性具有极 静态库 C B C A C D B D.framework A.framework 不宜多:动态库对其依赖的静态库具有 “吸附性” 的要求
15. 动态库对架构的要求 组件 C 组件 F 组件 A 组件 D 组件 G 组件 E 组件 H CFJ.framework 组件 C、F、J 理论上可以构成动态库 将来组件 C 需要依赖组件 D 怎么办 除 找到依赖完备的若 这对 程架构提出了极 组件 B 组件 J 组件,否则 法链接成功 的要求,很难实现并保持
16. 动态库相互依赖 Dev.framework Core.framework missing symbol A missing symbol B … … defining symbol B defining symbol A 动态库不可能存在相互依赖关系,任意静态库有可能强制转换动态库么?
17. 03 FocusLink 作流程
18. 动态查找符号 libPod1.a 编译: Missing Symbol A static linker 参数: -U/-undefined dynamic_lookup Dev.framework 运 : dyld Dynamic lookup symbol A Dev.framework Symbol A in Core.framework Dynamic lookup symbol A Core.framework Dev.framework
19. 运 时崩溃 Novel.o App libBook.a NSLog() main.o Novel.framework
20. 符号排查 可以 nm 命令排查 进制 件中的符号 发现 libBook.a 中确实有这个符号,但是链接进 Novel.framework 以后就没有了
21. Symbol Resolver buildAtomList 链接器解析符号本质上是 套 度优先(BFS) 算法, 只加载有必要的符号和 件,尽可能确保产物简单 resolveAllUndefines Input File 查找 加载 deadStripOptimize linkTimeOptimize undefined list 记录 symbol
22. 理想架构 Core.framework lib1.a lib3.a lib2.a Dev.framework lib4.a 对 lib6.a 有依赖关系 lib3.a lib3.a 和 lib4.a 不再参与 Core.framework 的链接 lib4.a lib4.a lib5.a lib6.a 转换为 Dev 动态库依赖 Core 动态库
23. 符号计算 Core.framework lib1.a lib3.a lib5.a Dev.framework lib2.a lib3.a lib4.a lib6.a X lib4.a lib3.a 和 lib4.a 不再参与 Core.framework 的链接 但实际情况是 lib6.a 中的 符号也可能受到影响,产物 可能会丢失符号 如果丢失的符号恰好被lib4 依赖,就会造成运 时崩溃
24. 符号计算 Core.framework lib1.a lib2.a lib3.a lib4.a Dev.framework lib3.a lib4.a lib5.a lib6.a 如何确保 Core.framework 完整性 对于任意 lib3.a 或 lib4.a 中的未定义符号,如果 lib1-2.a 和 lib5-6.a 中能 提供,必须确保这些符号出 现在 Core.framework 中
25. 链接器改造细节 调整符号可 性 LTO 性能优化 libPod.a + Framework Reserved symbols 确保符号加载 确保符号保留
26. 链接器改造细节 未定义符号加载流程,抽象成 search 函数以便复 保留符号,避免被优化消除
27. 链接器改造细节 性,运 强制调整符号可 时被 dyld 解析 修复 LTO bug 优化性能
28. 符号计算 计算 Core 动态库需要保留的符号 遍历 Dev.framework 中的未定义符号 检查 Core.framework 中是否包含这个符号 如果包含,则 Core.framework 需要保留这 些符号。对 Dev.framework 的处理也同理
29. 构建整体流程
30. 动态库选择策略 持
31. 代码适配 规范 Bundle 的获取 式 dyld 遍历 image 时适配多动态库
32. 04 总结与展望
33. FocusLink 案收益 优化前 80 单位:秒 优化后 80 60 60 40 30 20 0 10 10 产物安装 调试启动 1 链接
34. 未来展望 • 按照理想架构拆分更多动态库,优化 业务上多个独 尾场景下的性能 的模块,形成固定的动态库配置,减少 Core 动态库的复杂度、改动频率和改动成本 Core 动态库改动后,多个 相互依赖关系的动态库,彼此可以并 链接,发挥多核性能 • 跨模块不合理符号依赖关系识别标记,推动架构优化治理与准 原本业务上模块之间在链接层 独 的依赖难以识别并拦截,容易形成历史债务 配置动态库后,可以在链接时完成依赖隔离和治理,对于特殊情况也可以明确以 • 线性耗时优化为常数级耗时的思路,形成共识,在研发全链路推 式临时豁免 落地 程加载、编译、调试、索引等研发活动,先定位耗时瓶颈,再推动常数化耗时的优化策略落地 对于 pod install、 名单的
35.
36. THANKS 模型正在重新定义软件 Large Language Model Is Redefining The Software

Home - Wiki
Copyright © 2011-2025 iteam. Current version is 2.147.0. UTC+08:00, 2025-10-29 03:47
浙ICP备14020137号-1 $Map of visitor$