这个问题可能有点奇怪,但是我该如何加速g++编译时间?我的C ++代码大量使用boost和模板。我已经尽可能将头文件中的内容移到其他地方,并使用-j选项,但编译(和链接)仍然需要相当长的时间。
是否有任何工具可以分析我的代码并指出编译器的瓶颈?或者可以以某种方式对运行在我的代码上的编译器进行性能分析吗?这将非常好,因为有时我有这样的印象,花费太多时间盯着编译器控制台日志看......
这个问题可能有点奇怪,但是我该如何加速g++编译时间?我的C ++代码大量使用boost和模板。我已经尽可能将头文件中的内容移到其他地方,并使用-j选项,但编译(和链接)仍然需要相当长的时间。
是否有任何工具可以分析我的代码并指出编译器的瓶颈?或者可以以某种方式对运行在我的代码上的编译器进行性能分析吗?这将非常好,因为有时我有这样的印象,花费太多时间盯着编译器控制台日志看......
对我而言最有用的是:
-j3
。但请确保在Makefile中正确设置依赖图,否则可能会出现问题。-O0
。以下是我在一个非常类似的场景下加速构建所做的内容(包括boost、模板和gcc):
ccache
在使用分布式版本控制系统或者在团队中时非常有用,因为在这两种情况下,文件很可能已经被编译过了,即使它来自另一个位置。 - Matthieu M.我假设我们所讨论的是编译一个文件需要的分钟数,即预编译头文件或本地磁盘问题不是问题所在。
深度模板代码(boost等)的长时间编译通常根源于gcc在模板实例化方面的不友好渐近行为,特别是当模拟可变参数模板使用模板默认参数时。
这里有一份文件,将缩短编译时间作为可变参数模板的动机:
cpptruths有一篇文章介绍了gcc-4.5在这方面的表现更好,以及如何使用它的可变参数模板:
如果我没记错的话,BOOST有一种方法来限制伪可变参数的模板默认参数的生成,我认为“g++-DBOOST_MPL_LIMIT_LIST_SIZE=10”应该可以工作(默认值为20)
更新:这里有一个关于如何加速编译的通用技巧的很好的帖子,可能会有用:
更新:这个问题是关于编译模板时的性能问题,采纳的答案也推荐使用gcc-4.5,同时提到了clang作为一个良好的例子:
除了其他人所做的和你已经做的(并行构建,编译器选项等),请考虑将模板隐藏在通过接口访问的实现类中。这意味着,不要像这样拥有一个类:
// ClsWithNoTemplates.h file, included everywhere
class ClsWithTemplates
{
ComplicatedTemplate<abc> member;
// ...
public:
void FunctionUsingYourMember();
};
你应该具备以下技能:
// ClsWithNoTemplates.h file:
class ClsWithTemplatesImplementation; // forward declaration
// definition included in the ClsWithNoTemplates.cpp file
// this class will have a ComplicatedTemplate<abc> member, but it is only
// included in your ClsWithNoTemplates definition file (that is only included once)
class ClsWithNoTemplates
{
ClsWithTemplatesImplementation * impl; // no templates mentioned anywhere here
public:
void FunctionUsingYourMember(); // call impl->FunctionUsingYourMember() internally
};
这会稍微改变你的面向对象设计,但是这是有好处的:现在包括“ClsWithNoTemplates”的定义是快速的,并且你只需要(预)编译一次“ClsWithNoTemplates”的定义。
此外,如果你更改了实现代码,任何包含ClsWithNoTemplates.h的代码可能不需要重新定义。
这个改变应该会显著增加你的部分编译时间,并且它还有助于当你的ClsWithNoTemplates是从库文件导出的公共接口时:由于文件在你仅更改实现时不会被更改,你的依赖客户端代码根本不需要重新编译。
如果有很多文件,您可以通过只使用一个包含所有其他.cpp文件的.cpp文件来加快编译速度。当然,这需要您更加小心处理已经定义为每个文件的宏等,因为它们现在将被其他cpp文件看到。
如果有许多文件,这可以大大减少编译时间。
实例化更少的模板和内联函数。尽可能预编译并将其链接,而不是从头开始编译所有内容。确保使用最新版本的GCC。
然而,事实是C++是一种非常复杂的语言,编译它需要相当长的时间。
本文描述了一种编译模板代码的方法,类似于“传统”的非模板对象文件。每个模板实例化只需要一个代码开销,可以节省编译和链接时间。