如何减少编译时间和Visual c++项目(本机c++)的链接时间?

时间:2022-04-26 05:00:08

How do YOU reduce compile time, and linking time for VC++ projects (native C++)?

如何减少编译时间和vc++项目的链接时间(本机c++)?

Please specify if each suggestion applies to debug, release, or both.

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

12 个解决方案

#1


44  

It may sound obvious to you, but we try to use forward declarations as much as possible, even if it requires to write out long namespace names the type(s) is/are in:

这对您来说可能是显而易见的,但是我们尽量使用forward声明,即使它需要写出类型(s)所在的长名称空间名称:

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

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

It greatly reduces the time for compiling also on others compilers. Indeed it applies to all configurations :)

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

#2


21  

Use the Handle/Body pattern (also sometimes known as "pimpl", "adapter", "decorator", "bridge" or "wrapper"). By isolating the implementation of your classes into your .cpp files, they need only be compiled once. Most changes do not require changes to the header file so it means you can make fairly extensive changes while only requiring one file to be recompiled. This also encourages refactoring and writing of comments and unit tests since compile time is decreased. Additionally, you automatically separate the concerns of interface and implementation so the interface of your code is simplified.

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

#3


13  

If you have large complex headers that must be included by most of the .cpp files in your build process, and which are not changed very often, you can precompile them. In a Visual C++ project with a typical configuration, this is simply a matter of including them in stdafx.h. This feature has its detractors, but libraries that make full use of templates tend to have a lot of stuff in headers, and precompiled headers are the simplest way to speed up builds in that case.

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

#4


8  

These solutions apply to both debug and release, and are focused on a codebase that is already large and cumbersome.

这些解决方案既适用于调试,也适用于发布,并且集中于已经很大且很麻烦的代码库。

Forward declarations are a common solution.

转发声明是一种常见的解决方案。

Distributed building, such as with Incredibuild is a win.

分布式建筑,如超人特攻队就是一个胜利。

Pushing code from headers down into source files can work. Small classes, constants, enums and so on might start off in a header file simply because it could have been used in multiple compilation units, but in reality they are only used in one, and could be moved to the cpp file.

将代码从头文件下推到源文件可以工作。小类、常量、枚举等等可能仅仅因为可以在多个编译单元中使用而在头文件中启动,但实际上它们只在一个编译单元中使用,可以移动到cpp文件中。

A solution I haven't read about but have used is to split large headers. If you have a handful of very large headers, take a look at them. They may contain related information, and may also depend on a lot of other headers. Take the elements that have no dependencies on other files...simple structs, constants, enums and forward declarations and move them from the_world.h to the_world_defs.h. You may now find that a lot of your source files can now include only the_world_defs.h and avoid including all that overhead.

我还没读过但用过的解决方案是分割大标题。如果你有一些非常大的标题,看看它们。它们可能包含相关的信息,也可能依赖于许多其他的头信息。获取对其他文件没有依赖的元素…简单的结构、常量、枚举和转发声明,并将它们从the_world中移动。the_world_defs.h h。您现在可能会发现,您的许多源文件现在只包含了_world_defs。避免包括所有的开销。

Visual Studio also has a "Show Includes" option that can give you a sense of which source files include many headers and which header files are most frequently included.

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

For very common includes, consider putting them in a pre-compiled header.

对于非常常见的内容,请考虑将它们放入预编译的标题中。

#5


8  

I use Unity Builds (Screencast located here).

我使用Unity构建(位于这里的Screencast)。

#6


7  

The compile speed question is interesting enough that Stroustrup has it in his FAQ.

编译速度问题非常有趣,斯特鲁普在他的FAQ中有这个问题。

#7


7  

We use Xoreax's Incredibuild to run compilation in parallel across multiple machines.

我们使用Xoreax的神奇构建来并行地在多台机器上运行编译。

#8


5  

Also an interesting article from Ned Batchelder: http://nedbatchelder.com/blog/200401/speeding_c_links.html (about C++ on Windows).

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

#9


4  

Our development machines are all quad-core and we use Visual Studio 2008 supports parallel compiling. I am uncertain as to whether all editions of VS can do this.

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

We have a solution file with approximately 168 individual projects, and compile this way takes about 25 minutes on our quad-core machines, compared to about 90 minutes on the single core laptops we give to summer students. Not exactly comparable machines but you get the idea :)

我们有一个包含168个独立项目的解决方案文件,用这种方法编译我们的四核计算机大约需要25分钟,而我们给暑期学生的单核笔记本电脑大约需要90分钟。并不是完全可以相提并论的机器,但你有了这样的想法:

#10


2  

With Visual C++, there is a method, some refer to as Unity, that improves link time significantly by reducing the number of object modules.

使用Visual c++,有一种方法(有些称为Unity)可以通过减少对象模块的数量来显著提高链接时间。

This involves concatenating the C++ code, usually in groups by library. This of course makes editing the code much more difficult, and you will run into namespace collisions unless you use them well. It keeps you from using "using namespace foo";

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

Several teams at our company have elaborate systems to take the normal C++ files and concatenate them at compile time as a build step. The reduction in link times can be enormous.

我们公司的几个团队拥有复杂的系统,可以使用普通的c++文件,并在编译时将它们连接起来作为构建步骤。链接时间的减少是巨大的。

#11


1  

Another useful technique is blobbing. I think it is something similar to what was described by Matt Shaw.

另一个有用的技术是blobbing。我认为这和马特·肖的描述很相似。

Simply put, you just create one cpp file in which you include other cpp files. You may have two different project configurations, one ordinary and one blob. Of course, blobbing puts some constrains on your code, e.g. class names in unnamed namespaces may *.

简单地说,您只需创建一个cpp文件,其中包含其他cpp文件。您可能有两个不同的项目配置,一个普通的和一个blob。当然,blobbing会对代码造成一些限制,比如名称空间中的类名可能会发生冲突。

One technique to avoid recompiling the whole code in a blob (as David Rodríguez mentioned) when you change one cpp file - is to have your "working" blob which is created from files modified recently and other ordinary blobs.

当您更改一个cpp文件时,避免在blob中重新编译整个代码的一种技术是让您的“工作”blob从最近修改的文件和其他普通blobs中创建。

We use blobbing at work most of the time, and it reduces project build time, especially link time.

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

#12


0  

Compile Time:
If you have IncrediBuild, compile time won't be a problem. If you don't have a IncrediBuild, try the "unity build" method. It combine multiple cpp files to a single cpp file so the whole compile time is reduced.
Link Time:
The "unity build" method also contribute to reduce the link time but not much. How ever, you can check if the "Whole global optimization" and "LTCG" are enabled, while these flags make the program fast, they DO make the link SLOW.
Try turning off the "Whole Global Optimization" and set LTCG to "Default" the link time might be reduced by 5/6.
(LTCG stands for Link Time Code Generation)

编译时间:如果您有超人特工队,编译时间不会是个问题。如果你没有超人气,试试“统一构建”方法。它将多个cpp文件合并到一个cpp文件中,从而减少了整个编译时间。链接时间:“统一构建”方法也有助于减少链接时间,但并不多。无论如何,您都可以检查是否启用了“全局优化”和“LTCG”,尽管这些标志使程序运行得更快,但它们确实会使链接变慢。尝试关闭“全局优化”并将LTCG设置为“默认”,链接时间可能会减少5/6。(LTCG代表链路时间码生成)

#1


44  

It may sound obvious to you, but we try to use forward declarations as much as possible, even if it requires to write out long namespace names the type(s) is/are in:

这对您来说可能是显而易见的,但是我们尽量使用forward声明,即使它需要写出类型(s)所在的长名称空间名称:

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

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

It greatly reduces the time for compiling also on others compilers. Indeed it applies to all configurations :)

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

#2


21  

Use the Handle/Body pattern (also sometimes known as "pimpl", "adapter", "decorator", "bridge" or "wrapper"). By isolating the implementation of your classes into your .cpp files, they need only be compiled once. Most changes do not require changes to the header file so it means you can make fairly extensive changes while only requiring one file to be recompiled. This also encourages refactoring and writing of comments and unit tests since compile time is decreased. Additionally, you automatically separate the concerns of interface and implementation so the interface of your code is simplified.

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

#3


13  

If you have large complex headers that must be included by most of the .cpp files in your build process, and which are not changed very often, you can precompile them. In a Visual C++ project with a typical configuration, this is simply a matter of including them in stdafx.h. This feature has its detractors, but libraries that make full use of templates tend to have a lot of stuff in headers, and precompiled headers are the simplest way to speed up builds in that case.

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

#4


8  

These solutions apply to both debug and release, and are focused on a codebase that is already large and cumbersome.

这些解决方案既适用于调试,也适用于发布,并且集中于已经很大且很麻烦的代码库。

Forward declarations are a common solution.

转发声明是一种常见的解决方案。

Distributed building, such as with Incredibuild is a win.

分布式建筑,如超人特攻队就是一个胜利。

Pushing code from headers down into source files can work. Small classes, constants, enums and so on might start off in a header file simply because it could have been used in multiple compilation units, but in reality they are only used in one, and could be moved to the cpp file.

将代码从头文件下推到源文件可以工作。小类、常量、枚举等等可能仅仅因为可以在多个编译单元中使用而在头文件中启动,但实际上它们只在一个编译单元中使用,可以移动到cpp文件中。

A solution I haven't read about but have used is to split large headers. If you have a handful of very large headers, take a look at them. They may contain related information, and may also depend on a lot of other headers. Take the elements that have no dependencies on other files...simple structs, constants, enums and forward declarations and move them from the_world.h to the_world_defs.h. You may now find that a lot of your source files can now include only the_world_defs.h and avoid including all that overhead.

我还没读过但用过的解决方案是分割大标题。如果你有一些非常大的标题,看看它们。它们可能包含相关的信息,也可能依赖于许多其他的头信息。获取对其他文件没有依赖的元素…简单的结构、常量、枚举和转发声明,并将它们从the_world中移动。the_world_defs.h h。您现在可能会发现,您的许多源文件现在只包含了_world_defs。避免包括所有的开销。

Visual Studio also has a "Show Includes" option that can give you a sense of which source files include many headers and which header files are most frequently included.

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

For very common includes, consider putting them in a pre-compiled header.

对于非常常见的内容,请考虑将它们放入预编译的标题中。

#5


8  

I use Unity Builds (Screencast located here).

我使用Unity构建(位于这里的Screencast)。

#6


7  

The compile speed question is interesting enough that Stroustrup has it in his FAQ.

编译速度问题非常有趣,斯特鲁普在他的FAQ中有这个问题。

#7


7  

We use Xoreax's Incredibuild to run compilation in parallel across multiple machines.

我们使用Xoreax的神奇构建来并行地在多台机器上运行编译。

#8


5  

Also an interesting article from Ned Batchelder: http://nedbatchelder.com/blog/200401/speeding_c_links.html (about C++ on Windows).

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

#9


4  

Our development machines are all quad-core and we use Visual Studio 2008 supports parallel compiling. I am uncertain as to whether all editions of VS can do this.

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

We have a solution file with approximately 168 individual projects, and compile this way takes about 25 minutes on our quad-core machines, compared to about 90 minutes on the single core laptops we give to summer students. Not exactly comparable machines but you get the idea :)

我们有一个包含168个独立项目的解决方案文件,用这种方法编译我们的四核计算机大约需要25分钟,而我们给暑期学生的单核笔记本电脑大约需要90分钟。并不是完全可以相提并论的机器,但你有了这样的想法:

#10


2  

With Visual C++, there is a method, some refer to as Unity, that improves link time significantly by reducing the number of object modules.

使用Visual c++,有一种方法(有些称为Unity)可以通过减少对象模块的数量来显著提高链接时间。

This involves concatenating the C++ code, usually in groups by library. This of course makes editing the code much more difficult, and you will run into namespace collisions unless you use them well. It keeps you from using "using namespace foo";

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

Several teams at our company have elaborate systems to take the normal C++ files and concatenate them at compile time as a build step. The reduction in link times can be enormous.

我们公司的几个团队拥有复杂的系统,可以使用普通的c++文件,并在编译时将它们连接起来作为构建步骤。链接时间的减少是巨大的。

#11


1  

Another useful technique is blobbing. I think it is something similar to what was described by Matt Shaw.

另一个有用的技术是blobbing。我认为这和马特·肖的描述很相似。

Simply put, you just create one cpp file in which you include other cpp files. You may have two different project configurations, one ordinary and one blob. Of course, blobbing puts some constrains on your code, e.g. class names in unnamed namespaces may *.

简单地说,您只需创建一个cpp文件,其中包含其他cpp文件。您可能有两个不同的项目配置,一个普通的和一个blob。当然,blobbing会对代码造成一些限制,比如名称空间中的类名可能会发生冲突。

One technique to avoid recompiling the whole code in a blob (as David Rodríguez mentioned) when you change one cpp file - is to have your "working" blob which is created from files modified recently and other ordinary blobs.

当您更改一个cpp文件时,避免在blob中重新编译整个代码的一种技术是让您的“工作”blob从最近修改的文件和其他普通blobs中创建。

We use blobbing at work most of the time, and it reduces project build time, especially link time.

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

#12


0  

Compile Time:
If you have IncrediBuild, compile time won't be a problem. If you don't have a IncrediBuild, try the "unity build" method. It combine multiple cpp files to a single cpp file so the whole compile time is reduced.
Link Time:
The "unity build" method also contribute to reduce the link time but not much. How ever, you can check if the "Whole global optimization" and "LTCG" are enabled, while these flags make the program fast, they DO make the link SLOW.
Try turning off the "Whole Global Optimization" and set LTCG to "Default" the link time might be reduced by 5/6.
(LTCG stands for Link Time Code Generation)

编译时间:如果您有超人特工队,编译时间不会是个问题。如果你没有超人气,试试“统一构建”方法。它将多个cpp文件合并到一个cpp文件中,从而减少了整个编译时间。链接时间:“统一构建”方法也有助于减少链接时间,但并不多。无论如何,您都可以检查是否启用了“全局优化”和“LTCG”,尽管这些标志使程序运行得更快,但它们确实会使链接变慢。尝试关闭“全局优化”并将LTCG设置为“默认”,链接时间可能会减少5/6。(LTCG代表链路时间码生成)