对于C++程序员而言,编译、构建是每天都要做的操作。
所以,这是一个好话题。
当然,对于小项目,或者构建时间在5分钟以内的项目,这个话题不值一提。
假如项目构建一次需要耗时1小时以上时,那么这个话题事关程序员的工作效率,非常值得投入时间和精力来分析、改善项目构建的效率。
降低项目编译、构建的耗时,非常有助于提高工作效率,提高个人、团队整体的输出,改善工作、生活质量,减少无效加班。

观察C++程序在构建过程,比如在Windows平台,可以观察资源浏览器,可以发现构建过程中,CPU、内存、硬盘I/O的占用量会明显上升,并且随着代码量增大、这个现象会越发明显。
因此,在不修改现有实现的设计、代码时,最直观的改进方法即是换用更好的硬件,毕竟硬件成本可以摊薄,但人力成本则随着项目周期,稳步增长。

在单机构建的场景下,首先可以采用如下措施:

  • 主频更高的CPU,提升运算速度。
  • 更多核数的CPU,允许并行更多的任务。
  • 更大的内存,允许并行更多的任务,减少内存交换的次数。
  • 使用SSD硬盘,改善文件I/O的效率。

另外,为了提升硬件的利用效率:

  • 在Windows平台,使用MSVC构建时,可以考虑增加/MP选项,允许并行构建。
  • 在Windows平台或者Linux平台,使用make构建时,增加-jx,其中x为并行的任务数量,依据CPU核数和构建时资源使用情况,综合考虑给出具体取值。
  • 合理使用缓存策略,对于没有变化的编译单元,尽量复用已构建好的结果。
  • 关闭杀毒软件对C++项目所在目录的扫描操作。
  • 使用新版本的构建工具。

依据人多力量大的原则,可以使用成熟的集群构建技术,使用多台机器参与构建任务,进一步提升构建效率。
可用的软件比如:

  • Incredibuild,Windows平台下可以和MSVC配合使用。
  • distcc,Linux平台下与gcc/clang配合使用。
  • ccache,与distcc配合使用。
  • fastbuild,支持Windows、Linux平台。

下面从C++项目自身入手,寻找优化点。
分析C++源码项目构建的过程,可以划分为预处理、编译、链接三大过程。

  • 预处理,引入依赖的文件,将源文件处理为可独立编译的编译单元。
  • 编译,将编译单元转换为目标文件。
  • 链接,将目标文件整合为可执行文件、动态库或者打包为静态库。

对于预处理环节,可以做如下工作:

  • 在设计层面:

    • 合理规划模块,清晰定义模块之间的依赖关系和依赖顺序。
    • 合理定义模块之间的依赖,为并行构建提供可能性。
    • 减少模块对外暴露的头文件。
    • 减少头文件搜索路径,降低查找头文件引入的开销。
    • 合理定义头文件的用途。
  • 编码层面:
    • 使用PImpl策略,减少类定义变化引发的编译操作。
    • 合理使用前向声明策略,减少引入的头文件的数量。
    • 消除源码文件中冗余的头文件。
    • 清除废弃的头文件和源码文件。
    • 清理不必要的构建目标。
    • 控制C++技术比如模板的使用范围。
  • 构建系统,选择CMake和Ninja。
  • 使用CMake的UNITY_BUILD的特性,通过减少编译单元的数量,降低预处理引入的开销。

对于编译环节,可以做如下工作:

  • 单机构建时,使用前述的方法,使用更强劲的机器。
  • 使用构建集群,充分利用集群的优势。
  • 合理使用缓存技术,消除不必要的编译操作。
  • 开发人员本地构建时,可以关闭编译优化。
    • 对于MSVC,使用/Od/Ob0等选项、去掉/Gy等选项。
    • 对于gccclang,去掉-Os-O1-O2-O3-ffunction-sections-fdata-sections-flto等选项。
  • 版本构建时,启用编译优化。
    • 对于MSVC,使用/Gy/GF/O2/Ox/Ot/Oi/Oy等选项。
    • 对于gccclang,使用-Os-O1-O2-O3-ffunction-sections-fdata-sections-flto等选项。

对于链接环节,可以做如下工作:

  • 消除不必要的链接依赖。
  • 开发人员本地构建时,可以关闭链接时优化相关的选项,比如:
    • 对于MSVC,需要关闭选项/OPT:REF/OPT:ICF/OPT:LBR/ORDER等,同时关闭增量链接/INCREMENTAL。
    • 对于gccclang,需要关闭--icf=safe--icf=all-ffunction-sections-fdata-sections-Wl,–gc-sections-flto等选项。
  • 版本构建时,增加链接优化相关的选项。
    • 对于MSVC,增加选项/OPT:REF/OPT:ICF/OPT:LBR/ORDER等,启用增量链接/INCREMENTAL。
    • 对于gccclang,增加--icf=safe--icf=all-Wl,–gc-sections-flto等选项。

从设计角度,改善效率的措施一般有如下策略:

  • 时间换空间
  • 空间换时间
  • 串行改并行
  • 同步改异步
  • 单点优化
  • 消除冗余

依据这些策略,重新对前述优化措施进行归类:

  • 时间换空间

    • 链接时优化技术,降低构建结果的大小,降低后续使用时的成本,即制作安装盘、分发安装盘、软件安装时的时间成本。
  • 空间换时间
    • 搭建构建集群,多机并行编译。
    • 缓存,保留历史构建结果,消除不必要的构建操作。
  • 串行改并行。
    • 使用CMake和Ninja。
    • 优化模块设计。
  • 同步改异步。
    • 搭建构建集群,多机并行编译。
    • 优化模块设计。
  • 单点优化
    • 使用算力强劲的硬件。
    • 在本地开发时,关闭不必要的优化。
    • 版本构建时,开启优化。
  • 消除冗余。
    • 改善模块设计。
    • 清理冗余头文件和源码文件。
    • 清理冗余的链接依赖。
    • 禁止杀毒软件扫描项目所在的目录。

相关文章:

  • Recommendations to speed C++ builds in Visual Studio
  • 10 Tips to Improve Visual Studio Build Performance
  • Speed up Visual Studio Builds
  • Tip/Trick: Hard Drive Speed and Visual Studio Performance
  • Faster C++ builds, simplified: a new metric for time
  • Improving Compilation Time of C/C++ Projects
  • What techniques can be used to speed up C++ compilation times?
  • IncrediBuild: How to Speed up Your Project’s Build and Analysis

如何改善C++代码项目的构建效率,降低构建时间?相关推荐

  1. sonar检测java vue项目_Jenkins集成SonarQube 实现构建项目同时审查代码

    软件版本: SonarQube:7.7 Jenkins:2.164.3 一.简介 SonarQube是一个开源的代码质量分析平台,便于管理代码的质量,可检查出项目代码的漏洞和潜在的逻辑问题.同时,它提 ...

  2. Zadig 构建效率提升 40% 背后的实践思路

    构建"是软件工程师日常开发中的高频操作,也是生成可靠交付物的关键步骤.当前 Zadig 工作人员在设计层面对微服务架构有良好的支持,支持并行的构建.部署.测试多个服务.在 V1.10.0 版 ...

  3. 宜家如何利用低代码平台提升员工效率,提高数据价值

    低代码开发已经在全球范围内的不同行业.不同企业中得到应用,并且使用的场景.角色等也在不断拓展.本文介绍低代码在零售领域的应用:构建敏捷的客户服务管理案例.此案例中不仅介绍了明确的人物角色和场景背景,还 ...

  4. git 创建webpack项目_从 0 开始构建 webpack 项目【Webpack Book 翻译】

    在开始之前,请确保你使用的是 Node 的最新版本.至少是最新的 LTS(长期支持)版本,本书的配置基于 LTS 版本所写,你的终端需要有 node 和 npm 命令,Yarn 也是一个不错的选择,也 ...

  5. java 代码解析工具_改善 Java 代码质量的工具与方法

    原标题:改善 Java 代码质量的工具与方法 我们可能见过上面的有关代码质量的图片,究竟如何衡量一段代码好坏? 代码质量是什么?为什么它很重要? 作家通过他的著作来讲述了一个清晰的.令人信服的故事.他 ...

  6. 编写可读代码,提高工作效率

    本次分享是怎么做到"可读性"的 首先,正在进行的,说明下本文的可读性. 1.背景 根据今年形势996icu,加班加点的情况比较多.与其抱怨,不如改变. 从内因去改变:主题,编写可读 ...

  7. Webpack优化——将你的构建效率提速翻倍

    前言 今日早读文章由字节跳动@jerryOnlyZRJ授权分享. 正文从这开始-- 背景 随着构建体系不断完善.构建体验不断优化,webpack 已经逐渐成为了前端构建体系的一大霸主,对于工作中的真正 ...

  8. 水平时间轴css代码_使用CSS和JavaScript构建水平时间线

    水平时间轴css代码 在上一篇文章中 ,我向您展示了如何从头开始构建响应式垂直时间轴. 今天,我将介绍创建相关的水平时间线的过程. 与往常一样,要初步了解我们将要构建的内容,请查看相关的CodePen ...

  9. C++开源代码项目汇总

    Google的C++开源代码项目 v8  -  V8 JavaScript Engine V8 是 Google 的开源 JavaScript 引擎. V8 采用 C++ 编写,可在谷歌浏览器(来自 ...

最新文章

  1. 一文看懂Python(二)-----字符串篇
  2. 网易MCtalk Live:漫谈短视频平台概况,全面解读头部内容
  3. jfinal mysql 事务_jfinal事物为啥这么用不生效呢,只要执行update数据就进库了,数据库用的是oracle...
  4. Android Studio出现Failed to open zip file. Gradle's dependency cache may be corrupt问题的解决
  5. P2212 [USACO14MAR]Watering the Fields S(最小生成树)
  6. jni c 回调 java,JNI - 如何从C ++或C回调到Java?
  7. 常用类中的方法 —— java.lang.String
  8. 错误:cc1: error: unrecognized command line option “-m32”
  9. SQL中代替Like语句的另一种写法
  10. #pragma comment (lib, ws2_32.lib) 调用报错
  11. 服务器mt核心bug修复,RHSA-2020:0374-重要: 内核 安全和BUG修复更新 解决方法
  12. 哆啦A梦的神奇口袋 - 这全是宝藏
  13. C# Gridview 固定表头及表尾
  14. (组合数+快速幂+lucas+费马小引理)acwing 887. 求组合数 III
  15. Java面试题目分析
  16. 相似度系列-6:单维度方法:Evaluating Coherence in Dialogue Systems using Entailment
  17. 批量将磁盘上所有文件的路径地址、文件名、扩展名和文件夹名整理到 Excel 表格中
  18. drupal 中基本的数据库操作
  19. Delphi 通过TNetHTTPClient访问http,最新解析快手无水印视频地址链接方法
  20. shopee店铺装修的意义-扬帆志远

热门文章

  1. 网库“团计划”帮助企业搭乘团购快车
  2. Roofline模型初步
  3. Windows文件操作XCOPY命令的使用方法及参数详解
  4. 【附源码】计算机毕业设计java医疗物资管理系统设计与实现
  5. python如何打印_python如何打印
  6. 英雄远征Erlang源码分析(4)-TCP连接处理
  7. 使用C++实现MySQL数据库编程
  8. Ipopt-3.12.7在ubuntu18.04安装
  9. cleaner app Android,CCleaner
  10. 一起自学SLAM算法:8.2 Cartographer算法