【问题标题】:Why are templates so slow to compile?为什么模板编译这么慢?
【发布时间】:2011-04-07 17:54:03
【问题描述】:

大型模板项目编译速度很慢,从经验证据看来,STL 是造成这种情况的主要罪魁祸首。但是,为什么编译慢?

我之前通过观察头文件包含和组合编译单元来优化构建,但我不明白为什么模板库编译起来如此缓慢。

【问题讨论】:

    标签: c++ templates code-generation compilation


    【解决方案1】:

    由于古老的包含机制,C++ 通常编译速度很慢,这会导致编译器递归地重新解析每个标头及其所有声明和定义以及每个翻译单元所包含的所有内容

    模板只是建立在该“功能”之上。但是它们也要求所有代码都在标头中,这迫使编译器也重新解析所有包含的模板的所有实现

    【讨论】:

    • 当您前几次否决某个答案时,会弹出一个框,要求您解释为什么这样做。一段时间后,这种情况不再发生。但是,这并不是因为您不应该再解释否决票,而是因为到那时您必须知道这一点。大胆地说:你仍然应该解释你为什么投反对票。
    • 不确定,但可能有一个 C 迷过来并认为“古老的包含机制很好,C 编译速度足够快”
    • 预编译的头文件有助于解决这个问题 - 您可以预编译整个 STL,因此在编译项目时只解析一次。
    • @AshleysBrain:但是你最终会在任何地方都包含所有标准库(STL,顺便说一句,只是其中的一部分)。病毒包括 PCH 的扩散让我讨厌它们。如果您使用的是 GCC,DistGCC(或者不管它的拼写如何)是一个更好的解决方案;在 Windows 上是 [xoreax.com](IncrediBuild).
    • 我真的同意这种愚蠢的投票......无论如何,我认为模块仍然被考虑用于下一个标准(在 C++0x 之后)。另请注意,预编译的标头并不意味着包含所有内容,看看 Clang(以及序列化 AST 的可能性)应该可以避免解析阶段(最慢的),我真的对此很感兴趣。
    【解决方案2】:

    模板代码必须作为另一种语言来生成 C++ 代码。

    在这种思路下,模板化的代码必须被解析、执行,然后编译器才能生成C++代码,需要添加到当前的单元文件中,然后我们就可以编译整个C++代码了。

    我听说并非所有编译器都完全这样做,但这是主要思想,并且假设在真正编译代码之前还有很多事情要做,因为必须首先生成一些代码。

    【讨论】:

    • 这很慢,因为 gcc 和可能 vc++ 的编写者不会费心重用模板专业化,现在因为如果你在 10 个文件中使用 std::vector 标准充满了模板这整个过程进行了 10 次。哪个正在扼杀这种语言
    • @MartinKosicky 为什么生成代码会导致编译时间如此缓慢?
    • @piepi 因为即使 O(10n) 和 O(n) 被认为是相同的,我也称它们慢了 10 倍。如果您在 30 个不同的文件中使用 std::basic_string,就会发生这种情况
    【解决方案3】:

    部分答案在您的问题中。您不能在模板中查看标头包含,因为完整的实现必须包含在使用它们的每个编译单元中。

    【讨论】:

      【解决方案4】:

      想想真实世界的模板是什么——它不是真实的东西,而是关于如何构建真实事物的指导。

      对于 C++ 模板,头文件不包含实际的,例如'vector',但有关如何构建 vector 的说明。每次我们构建#includes <vector> 的源文件时,编译器都必须构建新的vector 代码,如果我们用不同的模板参数实例化vectors,可能会构建多次。

      每个源文件的构建都是独立的,不知道你是否已经为另一个源文件构建了vector,所以每次都构建一个新的。

      【讨论】:

        猜你喜欢
        • 2014-10-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-10-22
        • 2015-04-30
        • 1970-01-01
        • 2010-11-24
        • 2013-03-06
        相关资源
        最近更新 更多