6个回答

c++缩短编译时间作用大吗?

知乎用户
83个点赞 👍

上班等编译的时间顺手回答下,可以说是相当切题了..

TL;DR

相当重要。

先说说我的体会,再谈一些以前看到的趣闻。

六月初刚入职一个做存储产品的部门,几万行C++,再加上相关的库等等,规模也不算小了,一次完整编译,40~60分钟不等(O0 debug模式)。

刚来的那一周一直在看代码、gdb追踪,除了最开始build了一次(为了方便调试没开优化,debug模式,没有那么多编译、链接期优化)基本不用编译代码,因此无甚感受。

后面开始写gtest、写功能的时候就开始难受了...

不是在黑我司,跟同事前辈聊他们也说这两年代码也在拆了,你看我们那两个两万多行的Server和Servertest就是分拆之后的了

分拆之后的了

之后的了

的了

。。。

他们说的没错,我能看出来很多component现在是单独自己的文件、测试,但架不住核心模块很多还是缠在一起,变成些个巨无霸的.cc文件,这就直接导致:

  • compile时单个文件过大,大到编译它本身花的时间成为lock step中最长的,linker就在那等它编译完,它是显著的bottleneck
  • link时这个文件对外部的引用过多,又是没法并行化,导致link time解析符号表、重定位的时间巨长

粗略估计了下,只修改这单个巨无霸文件引发一次重编译、链接的时长大约在20分钟左右,其中1/4~1/3的时间是编译,剩下大头是链接。

我思考过这是不是我电脑太烂了,16英寸mbp 2019,i7-9750H,只有6个物理核。但后来我想了想也不是,或者不完全是。

我这个增量编译的场景压根儿不吃核心的,当然确实吃主频,可cpu主频也没办法scale up得上你代码膨胀的速度啊...

所以这确实是一个问题,而且是一个相当大的问题。我很久以前曾刷到

介绍ReScript解决的痛点

...
Scalability主要体现在编译性能上,我们可以在100ms左右增量编译一个10,000文件的大型项目,这点很符合大公司的胃口,因为大公司的代码库很大,编译性能严重影响程序员的生产力。

当时还很纳闷儿,有这么夸张吗?现在我明白了,操,什么吕布骑狗。。。

实际写代码,我自己有一些治标不治本的方法或许可能提供给各位参考(为了构建得快一点,我特么真的想了很多... 而这时候熟悉构建系统就很重要了),以cmake为例

  • 把不相干的target暂时注释掉,确保只构建你要测试的target
  • 把优化暂时关了,一方面单文件编译优化,另一方面C++是有很多链接期优化的,这些在规模大的时候也非常耗时
  • 如果功能非常独立(不依赖整个系统),可以暂时开一个单独的target,只build这一个小target,等测试得差不多了再把它加到主干target上测试
  • 多clone几个仓库,编译一个的时候在其他仓库上改其他分支...

最后附上一个趣闻(不是在黑rust,我也很喜欢rust,但这真的很难绷2333):据说,TiKV 一天只有 24 次编译机会,用一次少一次

...
TiDB 中的其他节点是用 Go 编写的,当然,Go 与 Rust 有不同的优点和缺点。PingCAP 的一些 Go 开发人员对于不得不等待 Rust 组件的构建而表示不满。因为他们习惯于快速的构建-测试迭代。

在 Go 开发人员忙碌工作的同时,Rust 开发人员却在编译时间休息(喝咖啡、喝茶、抽烟,或者诉苦)。Rust 开发人员有多余的时间来跨越内心的“阴影(译注:据说,TiKV 一天只有 24 次编译机会,用一次少一次)。
光度
8663 次赞同
去咨询

编辑于 2023-06-29 22:25・IP 属地上海
真诚赞赏,手留余香
还没有人赞赏,快来当第一个赞赏的人吧!
光度
自由评论 (0)
分享
Copyright © 2022 GreatFire.org