Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 每个C++;项目中作为预编译标头的标头_C++_Compilation_Precompiled Headers - Fatal编程技术网

C++ 每个C++;项目中作为预编译标头的标头

C++ 每个C++;项目中作为预编译标头的标头,c++,compilation,precompiled-headers,C++,Compilation,Precompiled Headers,通常的方法是在包含最常见的include的项目中有一个预编译头 问题是,它要么太小,要么太大。当它太小时,它不会覆盖所有使用过的标题,因此必须在每个模块中反复处理这些标题。当它太大时,编译速度会太慢,原因有两个: 当您更改预编译头中包含的头中的某些内容时,需要经常重新编译项目 预编译头太大,因此在每个文件中都包含它实际上会降低编译速度 如果我预先编译了项目中的所有头文件会怎么样。这将增加一些额外的编译器工作来预编译它们,但这样会非常好地工作,因为没有头需要处理两次(即使准备预编译头也会递归地使用

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

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

  • 当您更改预编译头中包含的头中的某些内容时,需要经常重新编译项目
  • 预编译头太大,因此在每个文件中都包含它实际上会降低编译速度
  • 如果我预先编译了项目中的所有头文件会怎么样。这将增加一些额外的编译器工作来预编译它们,但这样会非常好地工作,因为没有头需要处理两次(即使准备预编译头也会递归地使用预编译头),不需要在模块中添加额外的内容,只需要重新编译实际需要重新编译的模块。换言之,对于额外的工作O(n)复杂度,我将(理论上)优化C++中的O(n ^ 2)的共度。如果将预编译器设置为O(N),预编译数据的处理仍然是O(N^2),但至少最小化了

    有人试过这个吗?在现实场景中,它能提高编译时间吗?

    使用预编译头的可靠方法是使用一个(大)头(包括许多标准头…),并且可能在预编译头之后包含一些小头


    请参阅以获得更详细的解释(具体针对GCC)。

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

    只有当以下条件适用时,才能使用预编译头文件:

    • 在特定编译中只能使用一个预编译头
    实际上,可以将每个头编译为预编译头。(如果要验证是否包含所有内容,建议使用,如果要加快编译速度,则不建议使用)

    根据您的代码,您可以根据需要编译的代码决定使用不同的预编译头。然而,一般来说,它是头文件的编译时间、CPP文件的编译时间和维护之间的平衡

    添加一个简单的预编译头,该头已经包含多个标准头,如字符串、向量、映射、实用程序。。。已经可以显著提高编译速度。(很久以前,我注意到一个小项目有15-20%的回报)

    预编译头的主要好处在于:

    • 只需读取1个文件,而不必读取更多文件,这样可以提高磁盘访问能力
    • 读取针对读取而不是纯文本进行优化的二进制格式
    • 它不需要执行所有的错误检查,因为这在创建时就已经完成了
    即使您添加了一些不在任何地方都使用的标题,它仍然可以快得多

    最近,我还发现,对于大型项目来说,它并不理想(请参阅),但是,它可以让您了解时间花在哪里以及它可以改进什么。(或者您可以在代码库中改进什么)

    平心而论,我现在不使用预编译头。但是,我确实希望看到在我正在进行的项目中启用它

    还有一些有趣的内容:


    它在模板上失败。例如,您不能预编译,因为您不知道
    t
    将是什么。你可以用一堆类型来预编译它,但是哪些类型呢?我希望每个非平凡的头#都包含一些STL头,这使得这种方法不可行。文本包含文件将以内部二进制格式进行处理和准备,以供编译器稍后使用。模板显然需要再次编译,但至少文件不需要再次进行预处理。那么有什么好处呢?我不认为内部二进制格式的处理速度会明显快于标头本身,而且昂贵的优化步骤仍然需要重做。此外,您也不会删除相同类型的头文件的冗余重新编译。在每个TU中包含每个.h文件不太可能有效率。不仅仅是因为名称空间的污染,每一个微小的更改都会重新编译所有内容。当您有很少更改或从不更改的大型头时,预编译头非常有用。就像操作系统、框架、实用程序库一样。是的,我知道使用预编译头的标准方法,但这无助于在项目中重复处理头。