我们正在开发一个C++ library,目前有超过500个单独的.cpp文件。这些都被编译并存档到静态库中。即使使用并行构建,这也需要几分钟时间。我想减少这个编译时间。
每个文件平均有110行,其中有一个函数或两个函数。但是,对于每个.cpp文件,都有一个相应的.h标头,许多.cpp文件经常包含这些标头。例如,A.h
,A.cpp
,B.cpp
可能包含C.cpp
,等等。
我首先想要 profile 编译过程。有没有办法找出花多少时间做什么?我担心浪费很多时间只是打开头文件来检查包含警卫并忽略该文件。
如果这种事情是罪魁祸首,减少编译时间的最佳做法是什么?
我愿意添加新的分组标题,但可能不愿意更改这种多文件布局,因为这样我们的库也可以作为所需的标头库。< / p>
答案 0 :(得分:2)
如果这种事情是罪魁祸首,减少编译时间的最佳做法是什么?
如果您的预处理器支持#pragma once
指令,请使用它。这将确保.h文件不会被多次读取。
如果没有,请在.cpp文件中使用#include
警卫。
说你有
A.H:
#ifndef A_H
#define A_H
...
#endif
您可以在A.cpp中使用以下方法:
#ifndef A_H
#include "A.h"
#endif
您需要为每个.h文件重复该模式。 E.g。
#ifndef B_H
#include "B.h"
#endif
#ifndef C_H
#include "C.h"
#endif
您可以在What is the function of include guard in .cpp (not in .h)?的.cpp文件中详细了解#include
警卫的使用情况。
答案 1 :(得分:2)
我不知道你是否已经这样做了,但使用前向声明而不是标题中的include应该会提高编译速度。有关详细信息,请参阅此问题:
Should one use forward declarations instead of includes wherever possible?
减少编译时间的另一种方法是使用ccache
。它缓存了以前编译的结果。
答案 2 :(得分:2)
真的很难说。
我致力于改善我们工作项目的编译时间,发现ONE文件花了15分钟(在-O2
编译时,在-O0
编译约15秒)并编译两次,因此,总编译时间约为60-70分钟,这大约是一半时间。关闭一个优化功能使一个文件减少到大约20秒而不是15分钟...这个文件生成一个机器生成的函数和几万行长,这导致编译器做一些魔术很长的东西(大概是一些O(N ^ 2)算法)。
如果你有一个小函数然后依次调用许多小函数,最终通过内联层变成一个大文件,也会发生这种情况。
在其他时候,我发现减少文件数量并将更多代码放在一个文件中效果更好。
一般来说,我的经验(包括我自己的编译器项目,以及其他人/公司的编译器)都是因为它不是解析和读取花费时间的文件,但各种优化和代码生成通过。您可以通过使用-fsyntax-only
或编译器调用所有文件来编译所有文件。那将只读取源并检查它在语法上是否正确。如果您还没有,请尝试使用-O0
进行编译。通常,特定的优化过程是问题,有些过程比其他过程差,因此检查特定-O
选项中的个别优化通过是否有用 - 在gcc中可以列出{ {1}} [在这种情况下为-Q -O2 --help=optimizers
]。
你真的需要弄清楚编译器花费的时间。如果问题在于您花费大部分时间来优化代码,那么改变代码就没有意义。如果花费在解析上花费时间并且优化不会增加额外的时间,那么削减优化器就没有意义。如果没有真正建立你的项目,肯定很难说。
另一个提示是检查-O2
以查看您的编译进程是否每次使用100%cpu - 如果没有,您可能在编译器中没有足够的内存。我的工作项目有一个构建选项,它可以杀死&#34;我的台式机通过运行这么多的内存,整个系统只是停止 - 即使在网络浏览器中从一个选项卡切换到另一个选项卡需要15-30秒。唯一的解决方案是少运行top
[当然,我通常会忘记,并且在那时 - 所以如果我不想打断它,我会去吃午饭,长时间喝咖啡休息时间或者其他一些直到它完成,因为机器是不可用的]。这仅适用于调试版本,因为将大型代码库的调试信息放在一起会占用大量内存[显然!]
答案 3 :(得分:0)