你如何减少VC++项目(原生C++)的编译时间和链接时间?
请指定每个建议是否适用于调试,发布或两者.
这听起来很明显,但我们尝试尽可能多地使用前向声明,即使它需要写出类型中的长命名空间名称:
// Forward declaration stuff namespace plotter { namespace logic { class Plotter; } } // Real stuff namespace plotter { namespace samples { class Window { logic::Plotter * mPlotter; // ... }; } }
它大大减少了编译其他编译器的时间.确实它适用于所有配置:)
使用Handle/Body模式(有时也称为"pimpl","adapter","decorator","bridge"或"wrapper").通过将类的实现隔离到.cpp文件中,只需编译一次.大多数更改不需要更改头文件,因此这意味着您可以进行相当广泛的更改,同时只需要重新编译一个文件.这也鼓励重构和编写注释和单元测试,因为编译时间减少了.此外,您可以自动分离界面和实现的关注点,从而简化代码的界面.
如果您的构建过程中的大多数.cpp文件必须包含大型复杂标头,并且不经常更改,则可以预编译它们.在具有典型配置的Visual C++项目中,这只是将它们包含在stdafx.h中的问题.这个功能有它的批评者,但充分利用模板的库往往在头文件中有很多东西,预编译头文件是加速构建的最简单方法.
这些解决方案适用于调试和发布,并且专注于已经庞大且繁琐的代码库.
前向声明是一种常见的解决方案.
分布式建筑,例如Incredibuild是一个胜利.
将标头中的代码推送到源文件中可以正常工作.小类,常量,枚举等可能只是因为它可能已经在多个编译单元中使用而在头文件中开始,但实际上它们只用在一个中,并且可以移动到cpp文件中.
我没有读过但已经使用的解决方案是拆分大标头.如果您有一些非常大的标题,请查看它们.它们可能包含相关信息,也可能依赖于许多其他标题.获取对其他文件没有依赖性的元素...简单的结构,常量,枚举和前向声明,并将它们移动the_world.h
到the_world_defs.h
.您现在可能会发现很多源文件现在只能包含the_world_defs.h
并避免包含所有开销.
Visual Studio还有一个"显示包含"选项,可以让您了解哪些源文件包含许多标题以及最常包含哪些标题文件.
对于非常常见的包含,请考虑将它们放在预编译的头文件中.
我使用Unity Build(屏幕播放位于此处).
我们使用Xoreax的Incredibuild在多台机器上并行运行编译.
编译速度问题很有趣,Stroustrup在他的FAQ中有它.
另外一篇来自Ned Batchelder的有趣文章:http://nedbatchelder.com/blog/200401/speeding_c_links.html(关于Windows上的C++).