C++ 模块会使模板编译更快吗?

C++ 模块会使模板编译更快吗?,c++,c++11,C++,C++11,模块会使模板编译更快吗?模板(通常)只能是标题,并且最终位于#includer的翻译单元中 相关:预编译头是否会加快模板编译速度?根据模块提案,从您引用的论文来看,这是添加模块的三个主要目标中的第一个: 1简介 模块是一种封装库并封装其实现的机制。 它们不同于传统的翻译单位和标题的方法,主要是 所有实体仅在一个地方定义(即使是类、模板等)。本报 提出了一种模块机制(有点类似于模块a-2),具有三个 主要目标: 显著提高大型项目的构建时间 在接口和实现之间实现更好的分离 为现有库提供可行的过渡路

模块会使模板编译更快吗?模板(通常)只能是标题,并且最终位于#includer的翻译单元中


相关:预编译头是否会加快模板编译速度?

根据模块提案,从您引用的论文来看,这是添加模块的三个主要目标中的第一个:

1简介

模块是一种封装库并封装其实现的机制。 它们不同于传统的翻译单位和标题的方法,主要是 所有实体仅在一个地方定义(即使是类、模板等)。本报 提出了一种模块机制(有点类似于模块a-2),具有三个 主要目标:

  • 显著提高大型项目的构建时间
  • 在接口和实现之间实现更好的分离
  • 为现有库提供可行的过渡路径 虽然这些是驱动目标,但该方案也解决了许多其他长期存在的实用C++问题(初始化排序、运行时性能等)。
那么,他们如何实现这些目标呢?那么,从第4.1节:

由于标题文件通常包含在许多其他文件中,因此 构建周期的增长通常与源代码总量呈超线性关系 代码。如果这个问题没有得到解决,随着模板的使用,情况可能会变得更糟 增加更强大的声明性工具(如概念、契约编程、, 等)添加到语言中

模块通过替换文本包含机制(其 处理时间大致与预编译程序所包含的代码量成正比 模块连接机制(正确实施时的处理时间)- 与导入的声明数量大致成比例)。客户的财产 如果可以更改专用模块定义,则无需重新编译翻译单元 保留

换句话说,至少,解析这些模板所花费的时间只做了一次,而不是N次,这已经是一个巨大的改进

后面的部分描述了显式实例化等方面的改进。正如第5.8节所承认的,这并没有直接改善的一点是自动模板实例化。这里可以保证的是,您已经从预编译头中获得了完全相同的好处:“Set和Reset模块都必须实例化Lib::S,事实上,它们都在接口文件中公开了这个实例化。”但该提案随后给出了一些解决ODR问题的可能技术解决方案,至少其中一些还解决了多实例化问题,在当今世界可能不可能实现。例如,所建议的那种查询实例化已经被反复尝试过,通常认为很难正确使用今天的模型,但模块可能会使其可行。没有证据表明今天不可能做到正确,只是经验表明这很难,也没有证据表明使用模块会更容易,只是可能是这样

这符合提案中从未明确说明的一般含义,但背景是这样的:简化编译意味着我们可能会在过程中得到新的优化(直接的,因为更容易对正在发生的事情进行推理,或者间接的,因为一旦问题没有那么大的痛苦,就有更多的人来解决问题)


总之,如果没有其他原因,模板定义本身只需解析一次,那么模块可以而且肯定会使模板编译更快。它们可能会带来其他好处,这些好处在没有模块的情况下是不可能实现的,或者更难实现,但这可能无法保证。

我不知道模块,但我知道gcc甚至现在提供了预编译头,就像许多其他编译器一样。预编译头可以包含非常有效的机器可读版本的模板描述,因此当包含头时,可以跳过许多编译步骤,这通常是仅源文本未编译头所需的

本文讨论的模块是预编译接口文件,因此我假设当前的预编译头和新的预编译接口文件将提供类似的性能。从纯文本可移植模块描述创建这样的文件可能会更有效,因为由于语言语法的限制,它可以节省时间。而且它将更加标准化,因此更多的头文件将受益于预编译。当前项目很少预编译多个头,而根据我的经验,跨项目预编译头更为罕见

预编译头是否会加快模板编译速度

没有;它使模板无法编译。这就是PCH和模块的全部要点:停止编译所有内容

的思想是将“加载C++文本和编译”转换为“加载C++符号”。


现在,您仍然需要实例化模板(除非它们是在PCH/模块中实例化的)。但是,C++模板代码的编译成本被删除了。

C++中的模块是什么?我认为我不是唯一一个认为它不会提高模板构建时间的人。它说实体(包括模板)是在一个地方定义的,模块将显著缩短构建时间。除此之外,我没有从中推断出其他任何东西。我应该问他们如何改进模板构建时间。好吧,你可以阅读文档的其余部分。我将编辑我的答案以添加一个示例报价。我不确定是否遵循,但可以从模块、wi导出模板类