包含每个 header 是否会对性能产生影响?
Are there any performance implications to including every header?
假设我想使用 hex()
函数。我知道它在 <ios>
header 中定义,我也知道它包含在 <iostream>
header 中。不同之处在于 <iostream>
中有更多的功能和其他我不需要的东西。
从性能 stand-point 来看,我是否应该关心 including/defining 较少的功能,类 等而不是更多?
- 运行 时间性能没有受到影响。
- 但是,如果包含大量不必要的 header,编译时间可能会过长。
- 此外,完成此操作后,您可以创建不必要的重新编译,例如,如果 header 已更改但不使用它的文件包含它。
在小型项目中(包括小型 header),这无关紧要。随着项目的发展,它可能。
如果标准说它在 header <ios>
中定义,那么包括 header <ios>
因为你不能保证它会被包括 in/through任何其他 header.
包含不必要的 headers 有以下缺点。
- 更长的编译时间,链接器必须删除所有未使用的符号。
- 如果您在 CPP 中添加了额外的 header,它只会影响您的代码。
- 但是,如果您将代码作为库分发,并且在 header 文件中添加了不必要的 header。客户端代码将承担定位您使用的 header 的负担。
- 不要相信间接包含,使用实际定义所需函数的 header。
- 作为良好的编程习惯,在项目中也应包含 headers,以减少依赖性。
//local header -- most dependent on other headers
#include <project/impl.hpp>
//Third party library headers -- moderately dependent on other headers
#include <boost/optional.hpp>
//standard C++ header -- least dependent on other header
#include <string>
不受影响的是 run-time,链接器将在编译期间删除未使用的符号。
TL;DR:一般来说,最好只包含您需要的内容。包含更多 可以 对二进制大小和启动产生不利影响(应该是微不足道的),但主要是 compilation-time 没有预编译 headers.
当然,您必须至少包括那些 header,保证涵盖您的所有用途。
无论如何,有时 "work" 可能会发生这种情况,因为标准 C++ header 都允许按照实现者的意愿相互包含,并且 header 允许在std
-命名空间(参见 Why is "using namespace std" considered bad practice?)。
接下来,有时包含额外的 header 可能会导致创建额外的 objects(请参阅 std::ios_base::Init
),尽管 well-designed 库会最大限度地减少此类(即据我所知,标准库中的唯一实例)。
但最大的问题实际上不是编译(和优化)二进制文件的大小和效率(应该不受影响,除了前一点,其影响应该微乎其微),但 compilation-time 而积极发展(另见 How does #include <bits/stdc++.h> work in C++?)。
后者(严重到委员会正在研究 modules-proposal,参见 C++ Modules - why were they removed from C++0x? Will they be back later on?)因添加多余的 header 而受到不利影响。
除非,当然,你正在使用 precompiled-headers(参见 Why use Precompiled Headers (C/C++)?),在这种情况下,在预编译的 headers 中包含更多内容,因此到处都是,而不是仅在需要的地方,因为只要那些 header 不被修改,大多数时候实际上会减少 compile-times。
有一个 clang-based 工具可以找出最小 headers,叫做 include-what-you-use。
它分析了 clang AST 来决定,这既是优点也是缺点:
您不需要教它关于 header 提供的所有可用符号,但它也不知道在该修订版中事情是否以这种方式解决,或者它们是否符合合同。
所以你需要double-check它的结果。
包括不需要的 header 文件具有 一些 价值。
包含通常需要的 include
的剪切和粘贴确实需要更少的编码工作。当然,后来的编码现在因为不知道真正需要什么而受到阻碍。
尤其是在 C 中,其名称有限的 space 控件,包括不需要的 headers 会及时检测到冲突。假设代码定义了一个全局非 static
变量或函数恰好符合标准,例如 erfc()
来进行一些文本处理。通过包含 <math.h>
,可以检测到与 double erfc(double x)
的碰撞,即使此 .c
文件不进行 FP 数学计算,但其他 .c
文件会进行计算。
#include <math.h>
char *erfc(char *a, char *b);
OTOH,如果 .c
文件不包含 <math.h>
,在 link 时,将检测到碰撞。如果多年来代码库不需要 FP 数学而现在需要,只是检测在许多地方使用的 char *erfc(char *a, char *b)
,那么这种延迟通知的影响可能会很大。
IMO:尽合理的努力不包括不需要的 header 文件,但不要担心包括一些额外的文件,尤其是如果它们是常见的。如果存在自动化方法,请使用它来控制 header 文件包含。
假设我想使用 hex()
函数。我知道它在 <ios>
header 中定义,我也知道它包含在 <iostream>
header 中。不同之处在于 <iostream>
中有更多的功能和其他我不需要的东西。
从性能 stand-point 来看,我是否应该关心 including/defining 较少的功能,类 等而不是更多?
- 运行 时间性能没有受到影响。
- 但是,如果包含大量不必要的 header,编译时间可能会过长。
- 此外,完成此操作后,您可以创建不必要的重新编译,例如,如果 header 已更改但不使用它的文件包含它。
在小型项目中(包括小型 header),这无关紧要。随着项目的发展,它可能。
如果标准说它在 header <ios>
中定义,那么包括 header <ios>
因为你不能保证它会被包括 in/through任何其他 header.
包含不必要的 headers 有以下缺点。
- 更长的编译时间,链接器必须删除所有未使用的符号。
- 如果您在 CPP 中添加了额外的 header,它只会影响您的代码。
- 但是,如果您将代码作为库分发,并且在 header 文件中添加了不必要的 header。客户端代码将承担定位您使用的 header 的负担。
- 不要相信间接包含,使用实际定义所需函数的 header。
- 作为良好的编程习惯,在项目中也应包含 headers,以减少依赖性。
//local header -- most dependent on other headers #include <project/impl.hpp> //Third party library headers -- moderately dependent on other headers #include <boost/optional.hpp> //standard C++ header -- least dependent on other header #include <string>
不受影响的是 run-time,链接器将在编译期间删除未使用的符号。
TL;DR:一般来说,最好只包含您需要的内容。包含更多 可以 对二进制大小和启动产生不利影响(应该是微不足道的),但主要是 compilation-time 没有预编译 headers.
当然,您必须至少包括那些 header,保证涵盖您的所有用途。
无论如何,有时 "work" 可能会发生这种情况,因为标准 C++ header 都允许按照实现者的意愿相互包含,并且 header 允许在std
-命名空间(参见 Why is "using namespace std" considered bad practice?)。
接下来,有时包含额外的 header 可能会导致创建额外的 objects(请参阅 std::ios_base::Init
),尽管 well-designed 库会最大限度地减少此类(即据我所知,标准库中的唯一实例)。
但最大的问题实际上不是编译(和优化)二进制文件的大小和效率(应该不受影响,除了前一点,其影响应该微乎其微),但 compilation-time 而积极发展(另见 How does #include <bits/stdc++.h> work in C++?)。
后者(严重到委员会正在研究 modules-proposal,参见 C++ Modules - why were they removed from C++0x? Will they be back later on?)因添加多余的 header 而受到不利影响。
除非,当然,你正在使用 precompiled-headers(参见 Why use Precompiled Headers (C/C++)?),在这种情况下,在预编译的 headers 中包含更多内容,因此到处都是,而不是仅在需要的地方,因为只要那些 header 不被修改,大多数时候实际上会减少 compile-times。
有一个 clang-based 工具可以找出最小 headers,叫做 include-what-you-use。
它分析了 clang AST 来决定,这既是优点也是缺点:
您不需要教它关于 header 提供的所有可用符号,但它也不知道在该修订版中事情是否以这种方式解决,或者它们是否符合合同。
所以你需要double-check它的结果。
包括不需要的 header 文件具有 一些 价值。
包含通常需要的
include
的剪切和粘贴确实需要更少的编码工作。当然,后来的编码现在因为不知道真正需要什么而受到阻碍。尤其是在 C 中,其名称有限的 space 控件,包括不需要的 headers 会及时检测到冲突。假设代码定义了一个全局非
static
变量或函数恰好符合标准,例如erfc()
来进行一些文本处理。通过包含<math.h>
,可以检测到与double erfc(double x)
的碰撞,即使此.c
文件不进行 FP 数学计算,但其他.c
文件会进行计算。#include <math.h> char *erfc(char *a, char *b);
OTOH,如果 .c
文件不包含 <math.h>
,在 link 时,将检测到碰撞。如果多年来代码库不需要 FP 数学而现在需要,只是检测在许多地方使用的 char *erfc(char *a, char *b)
,那么这种延迟通知的影响可能会很大。
IMO:尽合理的努力不包括不需要的 header 文件,但不要担心包括一些额外的文件,尤其是如果它们是常见的。如果存在自动化方法,请使用它来控制 header 文件包含。