这个问题也许有点奇怪,但是我怎样才能加快g ++的编译时间呢?我的C ++代码大量使用boost和模板。我已经尽可能地将其移出了头文件,并使用了-j选项,但是编译(和链接)仍需要花费相当长的时间。
有没有工具可以分析我的代码并指出编译器的瓶颈?还是可以以某种方式分析运行在我的代码上的编译器?这真的很好,因为有时我会觉得我花了太多时间盯着编译器控制台日志...
这个问题也许有点奇怪,但是我怎样才能加快g ++的编译时间呢?我的C ++代码大量使用boost和模板。我已经尽可能地将其移出了头文件,并使用了-j选项,但是编译(和链接)仍需要花费相当长的时间。
有没有工具可以分析我的代码并指出编译器的瓶颈?还是可以以某种方式分析运行在我的代码上的编译器?这真的很好,因为有时我会觉得我花了太多时间盯着编译器控制台日志...
Answers:
对我来说最有用的是:
-j3
全球范围内都有业务。但是,请确保您的依赖性文件在Makefile中是正确的,否则您可能会遇到问题。-O0
,如果你不测试执行速度或代码大小(和你的电脑速度不够快,你没有太多在意(可能小)的性能损失)。这是我在您所描述的非常相似的场景(加速,模板,gcc)下加快构建速度的工作
ccache
当您使用DVCS或在团队中时,这将极大地帮助您,因为在两种情况下,即使文件是从另一个位置出现,也可能已经编译了文件。
我认为我们正在谈论分钟编译文件,即预编译头或本地磁盘的问题都不是问题。
带有深层模板代码(增强等)的长编译时间通常源于gcc在进行模板实例化时不友好的渐近行为,尤其是在使用模板默认参数模拟可变参数模板时。
这是一个文档,该文档以减少可变时间模板的名称命名缩短了编译时间:
cpptruths发表了一篇关于gcc-4.5如何更好地代表它以及如何使用可变参数模板出色地表现的文章:
IIRC然后BOOST有一种方法可以限制伪变量的模板默认参数的生成,我认为'g ++ -DBOOST_MPL_LIMIT_LIST_SIZE = 10'应该可以工作(默认值为20)
更新:这里还有一个不错的线程可以使用通用技术来加快在SO上的编译速度,这可能会很有用:
更新:这是关于编译模板时的性能问题,公认的答案也建议使用gcc-4.5,也提到clang作为一个积极的例子:
Compilation time for code that uses templates should now scale linearly with the number of instantiations rather than quadratically, as template instantiations are now looked up using hash tables.
除了其他人添加的内容和您已经在做的事情(并行构建,编译器选项等)之外,考虑将模板隐藏在可通过接口访问的实现类中。那意味着不用像这样的类:
// 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
};
这会稍微改变您的OOP设计,但这是有好处的:现在包括“ ClsWithNoTemplates”的定义很快,而且您仅(预)编译“ ClsWithNoTemplates”的定义一次。
另外,如果更改实现代码,则可能不需要重新定义任何包含ClsWithNoTemplates.h的代码。
此更改将大大增加您的部分编译时间,并且在ClsWithNoTemplates是从库文件导出的公共接口的情况下也将有所帮助:由于仅更改实现时该文件不会更改,因此从属客户端代码不会更改。完全不需要重新编译。
尝试使用PIMPL技术,这个问题是:可以使用哪些技术来加快C ++编译时间?
它将防止编译器在每次需要执行某些操作时都遵循头文件和实现的链条。
本文介绍了一种类似于“传统”非模板目标文件的编译模板代码的方法。节省编译和链接时间,每个模板实例化仅一行代码开销。
通常,最昂贵的编译部分是(a)读取源文件(全部),以及(b)将编译器加载到每个源文件的内存中。
如果您有52个源(.cc)文件,每个文件包括#include 47个#include(.h)文件,则将加载52次编译器,并浏览2496个文件。根据文件中注释的密度,您可能会花费大量时间吃掉无用的字符。(在我看到的一个组织中,头文件的注释在66%到90%之间变化,只有10%-33%的文件是“有意义的”。提高这些文件的可读性的最佳方法是剥离删除每个最后的注释,仅保留代码。)
仔细研究程序的物理结构。查看是否可以合并源文件,并简化#include文件的层次结构。
几十年前,像IBM这样的公司已经了解了这一点,因此会编写他们的编译器,以便可以将一系列要编译的文件(不仅是一个文件)交给编译器,并且编译器只能加载一次。