模块会使模板编译更快吗

Will modules make template compilation faster?

本文关键字:编译 模块      更新时间:2023-10-16

模块会使模板编译更快吗?模板(通常)只能是头,并且最终驻留在#includer的翻译单元中。

相关:预编译头是否使模板编译更快?

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

1简介

模块是一种封装库并封装其实现的机制。它们与翻译单位和标题文件的传统方法不同,主要在于所有实体都被定义在一个地方(甚至是类、模板等)提出了一种模块机制(有点类似于Modula-2),其中有三个主要目标:

  • 显著改善大型项目的建设时间
  • 实现接口和实现之间更好的分离
  • 为现有图书馆提供可行的过渡路径虽然这些都是驱动目标,但该提案还解决了许多其他长期存在的实际C++问题(初始化顺序、运行时性能等)

那么,他们如何才能实现这些目标呢?好吧,来自第4.1节:

由于标题文件通常包含在许多其他文件中构建周期的增长通常相对于源的总量是超线性的密码如果问题得不到解决,那么随着模板的使用,情况可能会变得更糟增加了和更强大的声明性设施(如概念、契约编程等),等等)被添加到该语言中。

模块通过替换文本包含机制(其处理时间与包含的代码量大致成比例)模块连接机制(其处理时间——当正确实现时--大致与导入的申报数量成比例)。客户的财产当可以更改私有模块定义时,无需重新编译翻译单元保留。

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

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

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

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

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

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

预编译头是否使模板编译更快?

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

其思想是将"加载C++文本并编译"转换为"加载C++符号"。模块是PCH的一种广义形式。

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