模块会更快地进行模板编译吗?

时间:2012-08-03 20:26:27

标签: c++ c++11

模块能否更快地进行模板编译?模板(通常)必须只是标题,最终驻留在#includer的翻译单元中。

相关:预编译头是否可以更快地进行模板编译?

3 个答案:

答案 0 :(得分:12)

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

  

1简介

     

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

     
      
  • 显着改善大型项目的构建时间
  •   
  • 在界面和实施之间实现更好的分离
  •   
  • 为现有库提供可行的转换路径   虽然这些是推动目标,但该提案还解决了许多其他长期存在的实际C ++问题(初始化排序,运行时性能等)。
  •   

那么,他们如何实现这些目标呢?好吧,从4.1节开始:

  

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

     

模块通过替换文本包含机制来解决这个问题   处理时间与预编译的处理时间大致成比例   模块附件机制(其处理时间 - 适当实施时 -   大致与导入的声明数成比例)。客户的财产   私有模块定义发生变化时,无需重新编译翻译单元   保留

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

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

这符合提案中从未明确说明的一般含义,但是在背景中:使编译更简单意味着我们可以在此过程中获得新的优化(直接,因为它更容易推断正在发生的事情,或者间接地,因为一旦没有这么大的痛苦,更多的人就会解决这个问题。)

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

答案 1 :(得分:0)

  

预编译头是否可以更快地进行模板编译?

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

我们的想法是将“加载C ++文本并编译”为“加载C ++符号”。模块是PCH的一种通用形式。

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

答案 2 :(得分:-1)

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

模块论文讨论了预编译的接口文件,因此我假设当前预编译的头文件和新的预编译接口文件将提供可比较的性能。从纯文本可移植模块描述创建这样的文件可能会更有效,因为它可以节省时间,因为语言语法的限制。它将更加标准化,因此更多标题将获得预编译的好处。目前的项目很少预编译多个标题,根据我的经验,跨项目预编译标题甚至更少。