项目中的每个C ++标头都是预编译的标头

时间:2015-12-10 10:15:40

标签: c++ compilation precompiled-headers

通常的方法是在项目中包含一个包含最常见包含的预编译头。

问题是,它太小或太大了。当它太小时,它不会覆盖所有使用的标题,因此必须在每个模块中反复处理这些标题。当它太大时,由于两个原因,它会使编译速度变慢:

  1. 当你在预编译头文件中包含的标题中更改某些内容时,需要经常重新编译项目。
  2. 预编译的标头太大,因此将其包含在每个文件中实际上会降低编译速度。
  3. 如果我在预编译的项目中创建了所有头文件,该怎么办?这将添加一些额外的编译器工作来预编译它们,但它会很好地工作,因为没有头必须处理两次(即使准备预编译的头将递归地使用预编译的头),不需要额外的东西被放入模块和仅实际需要重新编译的模块将被重新编译。换句话说,对于额外的工作O(N)复杂性,我会(理论上)优化C ++包含的O(n ^ 2)复杂性。对于O(N)的预检测器,预编译数据的处理仍然是O(N ^ 2),但至少是最小化的。

    有没有人试过这个?它可以在现实生活中增加编译时间吗?

2 个答案:

答案 0 :(得分:3)

我自己对带有预编译标头的GCC和Clang的经验是,每次编译只能提供一个预编译标头。另请参见GCC documentation,我引用:

  

仅在满足以下条件时才能使用预编译的头文件:

     
      
  • 在特定的编译中只能使用一个预编译的标头。
  •   
  • ...
  •   

在实践中,可以将每个标头编译为预编译的标头。 (如果要验证是否包含所有内容,建议使用,如果要加快编译速度,则不建议使用

根据您的代码,您可以根据需要编译的代码来决定使用其他预编译头。但是,通常,它是头文件的编译时间,CPP文件的编译时间与维护之间的平衡。

添加一个简单的预编译头文件,其中已经包含了几个标准头文件,例如字符串,向量,映射,实用程序……已经可以以显着的百分比加快编译速度。 (很久以前,我注意到一个小项目占15-20%)

从预编译头文件中获得的主要收益是:

  • 只需读取1个文件即可读取更多文件,从而改善了磁盘访问权限
  • 读取为阅读而非原始文本而优化的二进制格式
  • 它不需要进行所有错误检查,因为创建时已经完成了

即使添加了一些并非在所有地方都使用的标头,它仍然可以更快。

最近,我还发现了Clang build analyzer,它不是大型项目的理想选择(请参见issue on github),但是,它可以为您提供一些有关花费时间和时间的见解。可以改善。 (或者您可以在代码库中改进的地方)

公平地说,我目前不使用预编译的头文件。但是,我确实希望在我正在处理的项目中启用它。

其他一些有趣的读物:

答案 1 :(得分:1)

使用GCC,使用预编译头的可靠方法是使用一个(大)头(#include - 许多标准头...),并且可能包含一些 预编译后的标题

有关更详细的说明,请参阅this answer(特别针对GCC)。