41

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

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

4

12 回答 12

47

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

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

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

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

于 2008-12-12T21:52:11.417 回答
21

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

于 2008-12-12T22:18:59.723 回答
14

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

于 2008-12-12T22:46:56.250 回答
8

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

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

分布式构建,例如使用 Incredibuild 是一个胜利。

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

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

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

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

于 2008-12-12T23:13:28.833 回答
8

我使用Unity Builds位于此处的屏幕截图)。

于 2008-12-17T00:21:51.110 回答
7

我们使用Xoreax 的 Incredibuild在多台机器上并行运行编译。

于 2008-12-12T21:54:16.343 回答
7

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

于 2008-12-12T21:54:56.340 回答
5

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

于 2009-11-29T12:24:44.223 回答
4

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

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

于 2008-12-12T21:55:25.810 回答
2

在 Visual C++ 中,有一种方法称为 Unity,它通过减少对象模块的数量来显着改善链接时间。

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

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

于 2008-12-12T23:32:42.447 回答
1

另一种有用的技术是blobbing。我认为这与 Matt Shaw 所描述的相似。

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

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

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

于 2011-07-15T14:54:17.217 回答
0

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

于 2014-08-05T06:45:04.507 回答