在C/C++中,包含未使用的头文件会影响性能吗?

12

我有一个项目,每个C/C++文件都使用了大量的头文件。但是,每个C/C++文件使用的头文件中有70-80%是相同的。因此,为了使我的代码更易读,我计划将我需要的所有头文件都包含在一个单独的头文件common_headers.h中,并像这样在所有C/C++文件中引用它:

#include "common_headers.h"
现在这将包括所有必要的头文件,但也包括一些不会被单个文件使用的额外的头文件。我想知道这种做法是否会在运行时影响性能?我可以接受编译代码时多等几毫秒的延迟,但我想知道这是否会影响我的运行时性能?
所用头文件的说明:
1.大部分是标准的C/C++头文件。 2.用户定义的头文件中有内联的模板函数。 3.用户定义的头文件中没有静态函数。
这是我的编译器:g++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-3)

你的编译器支持预编译头文件吗? - M.M
6
如果其中一个头文件包含了static Foo foo { call_expensive_function(); };, 那么它就会......我猜我们在不知道这些头文件里面具体内容的情况下不能太具体。 - M.M
你是指编译时间性能下降还是询问执行时间性能是否会改变? - Eugene Podskal
@EugenePodskal 我更担心运行时性能而不是编译时性能。如果编译需要多几秒钟,我可以接受。 - Vivek V K
2
如果它们未被使用,目标文件可能会更大,但只要您使用-flto优化或旧版本的gcc -ffunction-sections -fdata-sections和--gc-sections,链接的二进制/库就不应该变大。在其他编译器上,您可能会看到一些膨胀。仅供参考,gtk使用<gtk/gtk.h>执行相同的操作,并且据我所知没有添加这些优化,但我并不是说我会将其用作良好编程实践的模型。 - technosaurus
4个回答

18

编译:

如果某些内容被包含在内,即便它最终不会被编译和链接,都必须进行分析,因此编译时间肯定会增加 - 不要包含未使用的头文件

运行时:

@DonReba已经提到,未使用的头文件可能包括一些pragma指令,可以更改生成的可执行文件,但通常情况下不会出现这种情况。

大多数未使用的函数和声明将被优化掉,除了一些特定情况 - 未使用的函数是否会被优化掉?。生成的exe文件可能会变大一些,但是这些函数和变量不会被使用,所以总体影响将是最小的。- 尽管如此,请勿包含未使用的头文件

总结:

如果您可以修改源代码以不包含任何不需要的内容-请修改它。

个人而言,我更喜欢自包含模块(头文件),它们包含所有需要的内容-没有多余的东西。这样的模块可以添加和删除,而无需事先考虑并避免留下一些不必要的依赖。它们仍然不是万无一失的,但结合注意力和一些代码分析,它们将使您的程序摆脱死板的头文件。

编辑:

预编译头文件:

预编译头文件用于减少编译时间较长但很少更改的头文件(系统头文件、大型项目头文件)的编译时间,因此,如果这些未使用的头文件包含在预编译头文件中,则在后续编译过程中的编译时间效果将被最小化。尽管如此,所有运行时问题,无论多么微小,仍然与简单的头文件包含相同。


我不明白为什么exe文件会变得更大,因为我没有包含任何一个C++文件中未使用的头文件。即使我在单独的文件中添加头文件,添加的头文件数量也是相同的,对吧? - Vivek V K
https://dev59.com/S2025IYBdhLWcg3wHR4Y 描述了编译和链接过程中哪些未使用的元素不会被优化。大多数头文件包含所谓的include guards或者#pragma once指令,所以同一个头文件的多次包含通常不会影响任何事情。但有时候由于某些原因可能没有包含这些保护措施,所以每次包含都会增加整个程序的大小 - 在现代C\C++中这通常很少用到。 - Eugene Podskal

2

这取决于编译器。现在大部分编译器都很智能,使用预编译头文件来提高性能。我使用支持预编译头文件的GCC编译器,据我所知不会影响性能。


1
Op明确指出他所说的是运行时而不是编译时性能。 - Keith

2

对于所提出的问题,简短的回答是:不行。

详细的回答如下:

更多的头文件意味着可能会出现一些问题,这些问题可能会表现为性能问题,但这真的不是一个问题。

许多人认为这样做是不好的风格,但也有人认为这是可以接受的。

避免这种风格的一个关键原因之一是它将使得循环依赖更容易出现。

由于我没有预编译头文件,我会建议避免使用这种风格以解决编译时间问题。


0

由于覆盖预处理指令,包含额外头文件可能会产生不同的运行时代码。但这并不是正常情况。

Visual C++、GCC 和 Clang 支持预编译头文件,以提高编译时间,适用于像您这样的用例。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接