包含每个标题是否会影响性能?

时间:2015-11-13 17:08:57

标签: c++ c header-files

假设我想使用hex()功能。我知道它在<ios>标头中定义,我也知道它包含在<iostream>标头中。不同之处在于<iostream>功能和其他我不需要的东西。

从性能角度来看,我是否应该关注包含/定义较少的函数,类等等?

5 个答案:

答案 0 :(得分:31)

如果标准说它在标题<ios>中定义,则包含标题<ios>,因为您无法保证它将包含在/通过任何其他标题。

答案 1 :(得分:27)

  • 没有运行时性能损失。
  • 但是,如果包含大量不必要的标题,可能会有过多的编译时间。
  • 此外,完成此操作后,您可以创建不必要的重新编译,例如,如果更改了标题但是没有使用它的文件包含它。

在小项目中(包括小标题),这并不重要。随着项目的发展,它可能会。

答案 2 :(得分:5)

TL; DR:一般来说,最好只包含您需要的内容。包含更多 can 会对二进制大小和启动产生负面影响(应该是无关紧要的),但主要是在没有预编译头的情况下会损害编译时间。

嗯,当然,你必须至少包括那些保证涵盖你所有用途的标题 它有时可能发生在&#34; work&#34;无论如何,因为标准C ++标题都允许在实现者想要的时候彼此包含,并且标题允许在std - 命名空间中包含其他符号(参见Why is "using namespace std" considered bad practice?)。

接下来,有时包含一个额外的标题可能会导致创建其他对象(请参阅std::ios_base::Init),尽管设计良好的库可以最小化(这是标准库中唯一的实例,据我所知)。

但是大问题实际上并不是编译(和优化)二进制文件的大小和效率(除了前一点,其影响应该是微不足道的,应该不受影响),但是在积极开发的同时编译时间(另见How does #include <bits/stdc++.h> work in C++?) 而且后者(严重地,非常多,以至于委员会正在制定模块提案,请参阅C++ Modules - why were they removed from C++0x? Will they be back later on?),因添加多余的标题而受到不利影响。

当然,除非您正在使用预编译头文件(请参阅Why use Precompiled Headers (C/C++)?),在这种情况下,在预编译头文件中包含更多内容,因此在所有地方而不是仅在需要的地方,只要这些头文件未被修改,实际上大多数时候都会减少编译时间。

有一个基于clang的工具可以找出最小标题,称为include-what-you-use 它分析了俚语AST来决定,这既是力量又是弱点:
您不需要教授标题提供的所有符号,但它也不知道事情是否在该修订中以某种方式解决,或者它们是否合同。
所以你需要仔细检查它的结果。

答案 3 :(得分:4)

包含不必要的标题有以下缺点。

  1. 编译时间越长,链接器必须删除所有未使用的符号。
  2. 如果您在CPP中添加了额外的标头,则只会影响您的代码。
  3. 但是,如果您将代码作为库分发,并且在头文件中添加了不必要的标头。客户端代码将因查找您使用过的标头而负担沉重。
  4. 不信任间接包含,使用实际定义所需功能的标头。
  5. 同样在项目中作为良好的编程习惯,应该按照减少依赖的顺序包含标题。
  6. //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>
    

    不受影响的事情是运行时,链接器将在编译期间删除未使用的符号。

答案 4 :(得分:1)

包含不需要的头文件有一些值。

  1. 包含通常需要的include的剪切和粘贴需要较少的编码工作。当然,后来的编码现在已经不知道真正需要什么了。

  2. 特别是在C中,由于其名称空间控制有限,包括不需要的标题会立即检测到冲突。假设代码定义了一个符合标准的全局非static变量或函数,例如erfc()来进行一些文本处理。通过包含<math.h>,可以使用double erfc(double x)检测到冲突,即使此.c文件没有FP数学,但其他.c文件也没有。

    #include <math.h>
    char *erfc(char *a, char *b);
    
  3. OTOH,如果此.c文件未包含<math.h>,则在链接时,将检测到冲突。如果多年来的代码库不需要FP数学,那么这个延迟通知的影响可能会很大,现在只能检测许多地方使用的char *erfc(char *a, char *b)

    IMO:尽合理努力不包含不需要的头文件,但不要担心包括一些额外的,特别是如果它们是常见的。如果存在自动方法,请使用它来控制头文件包含。