2012-10-06 35 views
0

如果我有一个C++模板我有两个选择(不出口关键字)将它们连接:C++模板性能纳入模型和在线模型

  • 与内联包含模式 - 即包括定义一起在.h文件中声明。这种内联的所有功能,并且没有内联创建一个大的单元(虽然它的懒惰)

  • 纳入模型 - 即像包括这个.h文件中:

代码:

// templateinstantiations.cpp 
#include "array.cpp" 
template class array <int, 50>; // explicit instantiation 

每次我想使用一个模板,并小心明确地实例化每一个我需要的类型(这可能很无聊,很难维护)

我的曲线注意的是:我知道过度内联函数可能会导致内存抖动和性能损失。此外,在上述两种情况下,编译时间似乎都很大......第一种和第二种方法之间的权衡是什么?是否有一个标准选择第一个或第二个我只需要尝试一下,并“时间”他们?

+0

Ehm ...只是做正常的方式,并担心提高编译时间,当他们真的从中受到影响?只是你知道,你的模板可能不会导致任何放缓。大部分stdlib都是模板,它们都只是在头文件中包含定义。 – Xeo

+2

回复:“(这可能很无聊,很难维护)” - 的确如此。除非你能够衡量**重大**的好处,否则不要这样做。在几乎所有情况下,都不要这样做。 –

+0

我更担心潜在的“内存抖动”现象,而不是“庞大的编译时间”,我有点“担心”内联方法 –

回答

1

这个问题是不是真正的模板,而是内联,我想。出于运行时性能的考虑,编译器在大多数情况下可能会做出正确的选择:如果它看到函数太大而无法从内联中获益,那么它可能会独立生成任何内联函数的非内联版本该功能是否是模板。每个翻译单元将创建它自己的函数版本,链接器将选择一个(并且希望抛弃其他未使用的副本,但是否确实取决于链接器和目标文件格式)。

当查看模板代码和它调用的函数之间的各种交互时,模板之间的交互可能是模板本身:当强制代码不内联时,编译器没有机会避免开销一个函数调用。通常,模板使用的抽象是非常简单的函数,例如,“增加迭代器”和“取消引用迭代器”映射到底层指针操作,由于函数调用开销和创建函数调用的开销, 。但是,编译器实际上可以看到这一点,并在许多情况下做出正确的选择。

这就是说,我是为某些模板创建显式实例化的忠实粉丝。例如,从头文件中移除IOStreams库的某些部分并在库中显式实例化它们会对编译时间产生巨大影响,特别是在优化开启的情况下:调用整数的简单输出函数会导致大量模板被实例化。把这段代码放到它自己的文件中并用合适的优化选项编译它可能不会在性能方面产生太大的差别,但它对编译时间有重大影响。不过这可能会对性能产生间接影响:您可以使用该库来支付更多的迭代来测试代码的性能。

0

即使你明确地声明功能inline没有保证C++使其inline,所以你认为如何实现所有在头一个模板将强制执行inline并引起你一些问题?

在几乎所有情况下你不需要第二种情况下,虽然你可以做到这样的,但并不需要它,以避免inline问题