【问题标题】:How expensive it is for the compiler to process an include-guarded header?编译器处理包含保护的标头有多昂贵?
【发布时间】:2011-07-13 23:21:06
【问题描述】:

为了加快大型源文件的编译速度,删减翻译单元中使用的大量标头是否更有意义,或者编译代码的成本是否远远超过处理一个包含保护的标头?

如果后者是真的,那么最好花在工程上的努力来创建更多、轻量级的标头,而不是更少。

那么现代编译器需要多长时间才能处理有效包含保护的标头?何时包含此类标头会影响编译性能?

(与this question相关)

【问题讨论】:

    标签: performance include preprocessor compiler-optimization


    【解决方案1】:

    前几天我阅读了一个关于此的常见问题解答...首先,编写 正确 标头,即包括您使用的所有标头,并且不依赖于未记录的依赖项(可能并且将会改变)。

    其次,现在编译器通常会识别包含守卫,因此它们相当有效。但是,您仍然需要打开很多文件,这可能会成为大型项目的负担。一个建议是这样做:

    头文件:

    // file.hpp
    
    #ifndef H_FILE
    #define H_FILE
    
    /* ... */
    
    #endif
    

    现在要使用源文件中的标头,添加一个额外的#ifndef

    // source.cpp
    
    #ifndef H_FILE
    #  include <file.hpp>
    #endif
    

    源文件中的噪音会更大,并且您需要可预测的包含保护名称,但您可能会避免使用很多类似的包含指令。

    【讨论】:

    • 你必须至少打开头文件一次,所以如果编译器快速检测到包含守卫你会得到什么?
    • @yi_H:第二个代码块进入源文件(我在其中编辑)。关键是如果file.hpp 已经被包含,你永远不需要打开 file.hpp 来找到它的包含保护。
    • 我不知道编译器是如何工作的,但是如果我写了一个,我会在一个标志中存储标头是否受到保护,如果是这样并且仍然定义了常量,那么就不需要打开并包含它再次。编译器是否使用这种机制?如果是这样,那么所有额外提议的警卫都是毫无意义的。
    • 他们很可能会这样做。在这种情况下,除非您愿意重组标头并创建仅前向声明的标头,否则您已经做得很好了。
    • 感谢您的评论。关于如何安排编译器处理包含保护的标头的能力的任何建议,如您上面描述的那样“预先保护”它们?
    【解决方案2】:

    假设 C/C++,头文件的简单重新编译对于大型系统(数百个文件)是非线性扩展的,所以如果编译性能是一个问题,很可能归结为这个问题。至少除非您尝试在 1980 年代的 PC 上编译一百万行源文件...

    预编译的头文件可用于大多数编译器,但通常需要特定的配置和管理才能处理非系统头文件,并非每个项目都这样做。

    参见示例:

    http://www.cygnus-software.com/papers/precompiledheaders.html

    '我的项目的构建时间现在是以前的 15%!'

    除此之外,您还需要查看以下技术:

    http://www.amazon.com/exec/obidos/ASIN/0201633620/qid%3D990165010/002-0139320-7720029

    或者将系统拆分为多个部分,在它们之间使用干净的、非基于标头的接口,例如 .NET 组件。

    【讨论】:

    • 我最近发现了 PCH(在与 Boost 战斗时),我很喜欢它们,但当被问及这个话题时,我得到了很多人的负面反应......
    【解决方案3】:

    答案:

    它可能非常昂贵!

    我发现了一篇文章,其中有人对此处解决的问题进行了一些测试,并且惊讶地发现,如果您编写的话,您可以将 MSVC 下的编译时间增加至少一个数量级你的 include 守卫正确:

    http://www.bobarcher.org/software/include/index.html

    结果中最令人惊讶的一行是,在 MSVC 2008 下编译的测试文件在使用正确的包含保护方法的情况下从 5.48 秒变为 0.13 秒。

    【讨论】:

      猜你喜欢
      • 2017-09-15
      • 2021-02-20
      • 2013-11-13
      • 2011-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-20
      • 1970-01-01
      相关资源
      最近更新 更多