如何改善C++代码项目的构建效率,降低构建时间?
对于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
等选项。 - 对于
gcc
和clang
,去掉-Os
、-O1
、-O2
、-O3
、-ffunction-sections
、-fdata-sections
、-flto
等选项。
- 对于MSVC,使用
- 版本构建时,启用编译优化。
- 对于MSVC,使用
/Gy
、/GF
、/O2
、/Ox
、/Ot
、/Oi
、/Oy
等选项。 - 对于
gcc
和clang
,使用-Os
、-O1
、-O2
、-O3
、-ffunction-sections
、-fdata-sections
、-flto
等选项。
- 对于MSVC,使用
对于链接环节,可以做如下工作:
- 消除不必要的链接依赖。
- 开发人员本地构建时,可以关闭链接时优化相关的选项,比如:
- 对于MSVC,需要关闭选项
/OPT:REF
、/OPT:ICF
、/OPT:LBR
、/ORDER
等,同时关闭增量链接/INCREMENTAL。 - 对于
gcc
和clang
,需要关闭--icf=safe
、--icf=all
、-ffunction-sections
、-fdata-sections
、-Wl,–gc-sections
、-flto
等选项。
- 对于MSVC,需要关闭选项
- 版本构建时,增加链接优化相关的选项。
- 对于MSVC,增加选项
/OPT:REF
、/OPT:ICF
、/OPT:LBR
、/ORDER
等,启用增量链接/INCREMENTAL。 - 对于
gcc
和clang
,增加--icf=safe
、--icf=all
、-Wl,–gc-sections
、-flto
等选项。
- 对于MSVC,增加选项
从设计角度,改善效率的措施一般有如下策略:
- 时间换空间
- 空间换时间
- 串行改并行
- 同步改异步
- 单点优化
- 消除冗余
依据这些策略,重新对前述优化措施进行归类:
- 时间换空间
- 链接时优化技术,降低构建结果的大小,降低后续使用时的成本,即制作安装盘、分发安装盘、软件安装时的时间成本。
- 空间换时间
- 搭建构建集群,多机并行编译。
- 缓存,保留历史构建结果,消除不必要的构建操作。
- 串行改并行。
- 使用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++代码项目的构建效率,降低构建时间?相关推荐
- sonar检测java vue项目_Jenkins集成SonarQube 实现构建项目同时审查代码
软件版本: SonarQube:7.7 Jenkins:2.164.3 一.简介 SonarQube是一个开源的代码质量分析平台,便于管理代码的质量,可检查出项目代码的漏洞和潜在的逻辑问题.同时,它提 ...
- Zadig 构建效率提升 40% 背后的实践思路
构建"是软件工程师日常开发中的高频操作,也是生成可靠交付物的关键步骤.当前 Zadig 工作人员在设计层面对微服务架构有良好的支持,支持并行的构建.部署.测试多个服务.在 V1.10.0 版 ...
- 宜家如何利用低代码平台提升员工效率,提高数据价值
低代码开发已经在全球范围内的不同行业.不同企业中得到应用,并且使用的场景.角色等也在不断拓展.本文介绍低代码在零售领域的应用:构建敏捷的客户服务管理案例.此案例中不仅介绍了明确的人物角色和场景背景,还 ...
- git 创建webpack项目_从 0 开始构建 webpack 项目【Webpack Book 翻译】
在开始之前,请确保你使用的是 Node 的最新版本.至少是最新的 LTS(长期支持)版本,本书的配置基于 LTS 版本所写,你的终端需要有 node 和 npm 命令,Yarn 也是一个不错的选择,也 ...
- java 代码解析工具_改善 Java 代码质量的工具与方法
原标题:改善 Java 代码质量的工具与方法 我们可能见过上面的有关代码质量的图片,究竟如何衡量一段代码好坏? 代码质量是什么?为什么它很重要? 作家通过他的著作来讲述了一个清晰的.令人信服的故事.他 ...
- 编写可读代码,提高工作效率
本次分享是怎么做到"可读性"的 首先,正在进行的,说明下本文的可读性. 1.背景 根据今年形势996icu,加班加点的情况比较多.与其抱怨,不如改变. 从内因去改变:主题,编写可读 ...
- Webpack优化——将你的构建效率提速翻倍
前言 今日早读文章由字节跳动@jerryOnlyZRJ授权分享. 正文从这开始-- 背景 随着构建体系不断完善.构建体验不断优化,webpack 已经逐渐成为了前端构建体系的一大霸主,对于工作中的真正 ...
- 水平时间轴css代码_使用CSS和JavaScript构建水平时间线
水平时间轴css代码 在上一篇文章中 ,我向您展示了如何从头开始构建响应式垂直时间轴. 今天,我将介绍创建相关的水平时间线的过程. 与往常一样,要初步了解我们将要构建的内容,请查看相关的CodePen ...
- C++开源代码项目汇总
Google的C++开源代码项目 v8 - V8 JavaScript Engine V8 是 Google 的开源 JavaScript 引擎. V8 采用 C++ 编写,可在谷歌浏览器(来自 ...
最新文章
- 一文看懂Python(二)-----字符串篇
- 网易MCtalk Live:漫谈短视频平台概况,全面解读头部内容
- jfinal mysql 事务_jfinal事物为啥这么用不生效呢,只要执行update数据就进库了,数据库用的是oracle...
- Android Studio出现Failed to open zip file. Gradle's dependency cache may be corrupt问题的解决
- P2212 [USACO14MAR]Watering the Fields S(最小生成树)
- jni c 回调 java,JNI - 如何从C ++或C回调到Java?
- 常用类中的方法 —— java.lang.String
- 错误:cc1: error: unrecognized command line option “-m32”
- SQL中代替Like语句的另一种写法
- #pragma comment (lib, ws2_32.lib) 调用报错
- 服务器mt核心bug修复,RHSA-2020:0374-重要: 内核 安全和BUG修复更新 解决方法
- 哆啦A梦的神奇口袋 - 这全是宝藏
- C# Gridview 固定表头及表尾
- (组合数+快速幂+lucas+费马小引理)acwing 887. 求组合数 III
- Java面试题目分析
- 相似度系列-6:单维度方法:Evaluating Coherence in Dialogue Systems using Entailment
- 批量将磁盘上所有文件的路径地址、文件名、扩展名和文件夹名整理到 Excel 表格中
- drupal 中基本的数据库操作
- Delphi 通过TNetHTTPClient访问http,最新解析快手无水印视频地址链接方法
- shopee店铺装修的意义-扬帆志远
热门文章
- 网库“团计划”帮助企业搭乘团购快车
- Roofline模型初步
- Windows文件操作XCOPY命令的使用方法及参数详解
- 【附源码】计算机毕业设计java医疗物资管理系统设计与实现
- python如何打印_python如何打印
- 英雄远征Erlang源码分析(4)-TCP连接处理
- 使用C++实现MySQL数据库编程
- Ipopt-3.12.7在ubuntu18.04安装
- cleaner app Android,CCleaner
- 一起自学SLAM算法:8.2 Cartographer算法