C++ 模板性能包含模型和内联模型

标签 c++ templates generics include

如果我有一个 C++ 模板,我有两种选择(没有 export 关键字)来链接它们:

  • 带内联的包含模型 - 即在 .h 文件中包含定义和声明。这会内联所有函数并创建一个大单元(尽管它很懒惰)

  • 没有内联的包含模型 - 即类似包含此 .h 文件的内容:

代码:

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

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

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

最佳答案

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

当查看模板代码和它调用的函数(可能是模板本身)之间的各种交互时,就会出现与模板的交互:当强制代码不被内联时,编译器没有机会避免函数调用。通常模板使用的抽象是非常简单的函数,例如,映射到底层指针操作的“递增迭代器”和“取消引用迭代器”,由于函数调用开销和失去优化机会,创建函数调用可能变得相当昂贵.然而,编译器实际上可以看穿这一点,并在很多情况下做出正确的选择。

也就是说,我非常喜欢为某些模板创建显式实例化。例如,从 header 中删除 IOStreams 库的某些部分并在库中显式实例化它会对编译时间产生巨大影响,尤其是在启用优化时:为整数调用简单的输出函数会导致实例化大量模板.将此代码放入其自己的文件中并使用适当的优化选项对其进行编译可能不会对性能产生太大影响,但它确实会对编译时间产生重大影响。不过,这可能会对性能产生间接影响:您可以使用该库进行更多迭代来测试代码的性能。

关于C++ 模板性能包含模型和内联模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12760744/

相关文章:

c++ - 实现信号量

c++ - 模板特化和静态局部变量

generics - 在函数参数中接受不同种类的ArrayList

c++ - 模板特化适用于 int 而失败于 double 作为一个类

java - 如何将泛型与类型参数和通配符一起使用?

java - 在 Java 中转换迭代器类型

c++ - 具有不同类型的 STL 谓词

c++ - 有 Arduino PID 代码的说明吗?

c++ - 什么时候将全局变量的地址作为模板参数传递有用?

c++ - 如何查看为模板类型参数推导的类型?