C++ 模板:模板是否内联?性能有缺点吗?
C++ Templates: Are template ínstantiations inlined? Are there drawbacks in performance?
当某些C++实体(如结构、类或函数)被声明为模板时,为所述实体提供的定义只是蓝图,必须实例化。
由于模板实体在声明时必须定义(通常是头文件),我有一个概念,我试图说服自己这是错误的,即当模板实例化后,它将由编译器内联。我想问一下是不是这样?
当我读到以下段落时,这个问题的答案引起了我的怀疑:
"模板可能会导致编译时间变慢,甚至可能更大可执行文件,尤其是使用较旧的编译器。"
较慢的编译时间是显而易见的,因为模板必须实例化,但为什么"可能更大的可执行文件"?应以何种方式对此进行解释?我应该将其解释为"许多函数都是内联的"还是"如果有许多模板实例化,可执行文件的大小会增加,也就是说,同一个模板用许多不同的类型实例化,这会导致同一实体的多个副本在那里"?
在后一种情况下,较大的可执行文件大小是否会导致软件运行速度较慢,因为必须将更多的代码加载到内存中,从而导致昂贵的分页?
此外,由于这些问题在某种程度上也与编译器有关,我对Visual C++编译器很感兴趣。关于大多数编译器所做工作的概括答案也能提供很好的见解。
提前谢谢。
由于模板实体在声明时必须定义(通常是头文件)
不是这样。您可以单独声明和定义模板类、方法和函数,就像您可以声明和定义其他类、方法或函数一样。
我有一个概念,我试图说服自己这是错误的,当模板被实例化后,它将被编译器内联。我想问一下是不是这样?
其中一些可能是,也可能是全部,也可能没有。编译器会做它认为最好的事情。
较慢的编译时间是显而易见的,因为模板必须实例化,但为什么"可能更大的可执行文件"?应以何种方式对此进行解释?
它可以有多种解释。就像一瓶阿斯普林含有警告"可能会引发<在此插入副作用>"一样。
我应该将其解释为"许多函数都是内联的"还是"如果有许多模板实例化,可执行文件的大小会增加,也就是说,同一个模板用许多不同的类型实例化,这会导致同一实体的多个副本在那里"?
您不会有同一实体的多个副本——编译器套件必须注意这一点。即使方法是内联的,方法的地址也会:
- 始终存在,并且
- 当被多个编译单元引用时是相同的地址
你可能会发现,你开始创建比你想要的更多的类型。例如,std::vector<int>
是与std::vector<double>
完全不同的类型。CCD_ 3是与CCD_ 4不同的函数。程序中的类型和函数定义的数量可能会快速增长。
在后一种情况下,较大的可执行文件大小是否会导致软件运行速度较慢,因为必须将更多的代码加载到内存中,从而导致昂贵的分页?
分页过多,可能不会。很可能是缓存未命中过多。通常,优化较小的代码是实现良好性能的好策略(在某些情况下,例如访问的数据很少,而且都在缓存中)。
它们是否内联始终取决于编译器。所有类似的实例化都共享非内联模板实例化。
因此,许多想要制作Foo<int>
的翻译单元都将共享Foo实例化。显然,如果Foo<int>
是一个函数,并且编译器在每种情况下都决定内联它,那么代码就会重复。然而,选择内联是因为这样做的优化似乎很可能优于函数调用。
从技术上讲,可能是模板导致执行速度减慢的一个角落。我从事的软件有超紧密的内部环路,我们为此做了很多性能测量。我们使用了许多模板函数和类,与手工编写代码相比,它还没有表现出退化。
我不能确定,但我认为你必须有这样一种情况:-生成的非内联代码-对多个实例化执行此操作-可能是一个手写的函数-手工编写的函数不会因为是一个函数而受到运行时惩罚(即:没有涉及运行时检查的隐式转换)
然后,您可能会遇到这样的情况:单个手写函数适合CPU的指令缓存,但多个模板实例化不适合。
- 在头文件上包含 cpp 文件是否有缺点?
- 提供运算符+或运算符到双向迭代器有什么缺点吗?
- 与普通变量相比,仅仅读取原子变量的性能有什么不同吗
- 函数局部静态变量:从性能角度来看的优点/缺点
- std::atomic_flag不提供加载或存储操作有什么缺点吗?(自旋锁定示例)
- 指针和程序性能之间有什么关系吗?
- 与纯 V8 相比,NodeJS 是否有任何性能缺陷或显著开销?
- 使用std::tie进行类似golang的错误处理,同时返回结果,是否有缺点?(C++11)
- 从不可复制派生 AbstractBaseClasses (ABC) 是否有缺点?
- std::函数有性能问题,如何避免?
- 在类中始终使用此指针是否有任何性能成本
- 每个帧的参考中都有多少性能影响
- tcmalloc 与纯堆栈分配性能有多接近
- 守护进程()有什么缺点吗?
- 在循环体内宣布变量有任何缺点
- OOP——使用静态方法有缺点吗
- 在 c++ 中使用 "this" 关键字对性能有影响吗?
- 初始化方法与构造函数加赋值的方法——性能有什么不同?(C++)
- C++ 模板:模板是否内联?性能有缺点吗?
- 用Visual Studio c++编译器编译C代码有任何(与性能相关的)缺点吗?