你如何减少编译时间和链接Visual C ++项目(原生C ++)的时间?

时间:2008-12-12 21:46:19

标签: c++ visual-c++ compilation

你如何减少编译时间和VC ++项目的连接时间(原生C ++)?

请指定每个建议是否适用于调试,发布或两者。

12 个答案:

答案 0 :(得分:44)

这听起来很明显,但我们尝试尽可能多地使用前向声明,即使它需要写出类型所在的长命名空间名称:

// Forward declaration stuff
namespace plotter { namespace logic { class Plotter; } }

// Real stuff
namespace plotter {
    namespace samples {
        class Window {
            logic::Plotter * mPlotter;
            // ...
        };
    }
}

它大大减少了编译其他编译器的时间。实际上它适用于所有配置:)

答案 1 :(得分:21)

使用the Handle/Body pattern(有时也称为“pimpl”,“adapter”,“decorator”,“bridge”或“wrapper”)。通过将类的实现隔离到.cpp文件中,只需编译一次。大多数更改不需要更改头文件,因此这意味着您可以进行相当广泛的更改,同时只需要重新编译一个文件。这也鼓励重构和编写注释和单元测试,因为编译时间减少了。此外,您可以自动分离界面和实现的关注点,从而简化代码的界面。

答案 2 :(得分:14)

如果您的构建过程中的大多数.cpp文件必须包含大型复杂标头,并且不经常更改,则可以预编译它们。在具有典型配置的Visual C ++项目中,这只是将它们包含在stdafx.h中的问题。这个功能有它的批评者,但是充分利用模板的库往往在头文件中有很多东西,预编译头文件是加速构建的最简单方法。

答案 3 :(得分:8)

这些解决方案适用于调试和发布,并且专注于已经庞大且繁琐的代码库。

前瞻性声明是一种常见的解决方案。

分布式建筑,例如Incredibuild是一个胜利。

将标头中的代码推送到源文件中可以正常工作。小类,常量,枚举等可能只是因为可能在多个编译单元中使用而在头文件中开始,但实际上它们仅用于一个,并且可以移动到cpp文件。

我没有读过但已经使用的解决方案是拆分大标头。如果您有一些非常大的标题,请查看它们。它们可能包含相关信息,也可能依赖于许多其他标题。获取对其他文件没有依赖性的元素...简单的结构,常量,枚举和前向声明,并将它们从the_world.h移动到the_world_defs.h。您现在可能会发现很多源文件现在只能包含the_world_defs.h并避免包含所有开销。

Visual Studio还有一个“显示包含”选项,可以让您了解哪些源文件包含多个标头以及最常包含哪些标头文件。

对于非常常见的包含,请考虑将它们放在预编译的标题中。

答案 4 :(得分:8)

我使用Unity Builds(Screencast located here)。

答案 5 :(得分:7)

我们使用Xoreax's Incredibuild在多台计算机上并行运行编译。

答案 6 :(得分:7)

编译速度问题很有趣,Stroustrup在他的FAQ中有它。

答案 7 :(得分:5)

另一篇来自Ned Batchelder的有趣文章:http://nedbatchelder.com/blog/200401/speeding_c_links.html(关于Windows上的C ++)。

答案 8 :(得分:4)

我们的开发机器都是四核的,我们使用Visual Studio 2008支持并行编译。我不确定VS的所有版本是否都能做到这一点。

我们有一个包含大约168个单独项目的解决方案文件,在我们的四核机器上编译这种方式大约需要25分钟,相比之下,我们为夏季学生提供的单核笔记本电脑大约需要90分钟。不完全可比的机器,但你明白了:)

答案 9 :(得分:2)

使用Visual C ++,有一种方法,有些称为Unity,可以通过减少对象模块的数量来显着缩短链接时间。

这涉及连接C ++代码,通常按库分组。这当然使得编辑代码变得更加困难,除非你很好地使用它们,否则你将遇到命名空间冲突。它使您无法使用“using namespace foo”;

我们公司的几个团队都有精心设计的系统来获取普通的C ++文件,并在编译时将它们连接起来作为构建步骤。链接时间的缩短可能是巨大的。

答案 10 :(得分:1)

另一种有用的技术是斑点。我认为这与Matt Shaw描述的类似。

简单地说,您只需创建一个cpp文件,其中包含其他cpp文件。您可能有两种不同的项目配置,一种是普通配置,另一种是blob。当然,blobbing会对你的代码产生一些限制,例如:未命名的命名空间中的类名可能会发生冲突。

当你改变一个cpp文件时,避免重新编译blob中的整个代码的一种技术(正如DavidRodríguez提到的那样)是让你的“工作”blob是从最近修改过的文件和其他普通blob创建的。

我们大部分时间都在工作中使用blobbing,它减少了项目构建时间,尤其是链接时间。

答案 11 :(得分:0)

编译时间:
如果您有IncrediBuild,编译时间不会成为问题。如果您没有IncrediBuild,请尝试使用" unity build"方法。它将多个cpp文件组合到一个cpp文件中,从而减少了整个编译时间。
链接时间:
"统一构建"方法也有助于减少链接时间但不多。但是,您可以查看"整体全局优化"和" LTCG"启用,而这些标志使程序快速,他们确实使链接缓慢。
尝试关闭全局优化"全局优化"并将LTCG设置为"默认"链接时间可能会减少5/6。
(LTCG代表链路时间码生成)