2009-11-20 72 views
12

似乎在C++和D中,静态编译的语言以及模板元编程是一种流行技术的语言,模板实例化膨胀有一个相当大的担忧。在我看来,除非是资源受限的嵌入式系统,否则大多数情况下都是理论上的问题。在嵌入式领域之外,我还没有听说过某个人能够证明在实践中这是一个问题的例子。什么时候模板实例化在实践中膨胀很重要?

任何人都可以提供一个例子以外的严重资源有限的嵌入式系统,其中模板实例膨胀在实践要紧,不得不衡量,几乎显著负面影响?

回答

10

C++中没有什么问题,因为你在可以用做的模板东西的数量受其复杂性的限制。

但是,在CTFE(编译时函数评估)存在之前,我们不得不使用字符串处理模板。这也是在DMD中压缩了巨大符号的原因 - 用作模板参数的字符串成为损坏的符号名称的一部分,并且当使用更长的代码段(例如)实例化模板时,生成的符号大小会壮观地爆炸对象格式。

现在比较好。但总体而言,模板仍然因为一个简单的原因导致大量的膨胀 - 它们解析速度更快,并且比C++更强大,因此人们自然使用它们(即使在技术上不会需要模板的情况下) 。我必须承认我是这里的主要犯罪分子之一(如果你喜欢,请看tools.base,但一定要保留一个方便的barf包 - 该文件实际上是90%的模板代码)。

3

我认为你需要找到一个较老的编译器来在实践中看到模板代码的膨胀。现代C++编译器(和连接器)已经能够优化它一段时间了。

2

我认为这主要是心理膨胀。下一个编写代码的程序员首先需要弄清楚它的哪个子集很重要。

7

模板膨胀是不是问题(这是一个心理问题,而不是代码问题)。

是的,它可以变大。但有什么选择?
您可以自己手动编写所有代码(每种类型一次)。你认为手动写入会使它更小。编译器只实例化它实际需要的版本,链接器将删除遍布编译单元的多个副本。

所以没有实际的膨胀。
它只是建立你使用的。如果你使用很多不同的类型,你需要编写更多的代码。

+2

这不是完全正确 - 编译器可以生成相同的代码的不同功能'˚F(符号的int)'和'˚F<无符号整数>(无符号整数)',和probabl你不会注意到它们是相同的。而手动写入你只会得到这些功能之一。 – 2009-11-20 18:06:13

+2

理想情况下,您应该使用可识别并删除重复生成的汇编代码的编译器/链接器。 Visual Studio可以做到这一点(COMDAT折叠)。 – vividos 2009-11-20 18:59:17

+3

如果您只是使用模板作为泛型,则这是真实的。 但是,如果您正在使用模板进行元编程,则不是这样。元编程中使用的模板可以实例化各种你不需要的疯狂中间类型。我认为boost :: spirit解析器生成器可能就是一个很好的例子。 – Baxissimo 2009-11-20 19:31:51

1

模板实例膨胀是一个实践中的问题,因为它可以增加(很多!!!)编译和链接时间。

我personnaly认为,C##1问题是编译时间,它主要是由于模板。

我在一个有大约50个库的项目上工作。我们有我们自己的使用模板的rtti系统。我不得不重写,因为模板的臃肿

下面是一些数字:

  • 库从640兆字节去420兆字节
  • 临时工从4.3 GB的去了2.9 GB的
  • 完全重建从去19:30至13:10
+0

为什么反对? – benoitj 2011-01-18 11:01:07

+0

听起来像是一个“游戏项目”;)大多数PC游戏都会遇到这个问题,并且开发人员通常会在模板中发现问题。但实际上这个问题只是普通代码的膨胀,并且不负责任地在这件事上抛出了越来越多的库。由模板代码生成的代码膨胀通常只是替罪羊。 – Frunsi 2011-06-12 12:23:47