C++;模板:是模板&#x;NSTATIONS内联?在性能上有缺点吗? 当某个C++实体,如结构、类或函数被声明为模板时,为这些实体提供的定义仅是蓝图,必须实例化。

C++;模板:是模板&#x;NSTATIONS内联?在性能上有缺点吗? 当某个C++实体,如结构、类或函数被声明为模板时,为这些实体提供的定义仅是蓝图,必须实例化。,c++,performance,templates,C++,Performance,Templates,由于模板实体必须在声明时定义(通常是头文件),我有一个想法,我试图说服自己这是错误的,即当模板被实例化后,它将由编译器内联。我想问一下,这是不是真的 当我读到这一段时,对此的答案引起了我的怀疑: “模板可能会导致编译时间变慢,甚至可能导致编译时间变长 可执行文件,尤其是使用较旧的编译器。“ 编译速度较慢是显而易见的,因为模板必须实例化,但为什么“可能更大的可执行文件”?这应该以什么方式来解释?我应该将其解释为“许多函数都是内联的”还是“如果有许多模板实例化,可执行文件的大小就会增加,也就是说,同

由于模板实体必须在声明时定义(通常是头文件),我有一个想法,我试图说服自己这是错误的,即当模板被实例化后,它将由编译器内联。我想问一下,这是不是真的

当我读到这一段时,对此的答案引起了我的怀疑:

“模板可能会导致编译时间变慢,甚至可能导致编译时间变长 可执行文件,尤其是使用较旧的编译器。“

编译速度较慢是显而易见的,因为模板必须实例化,但为什么“可能更大的可执行文件”?这应该以什么方式来解释?我应该将其解释为“许多函数都是内联的”还是“如果有许多模板实例化,可执行文件的大小就会增加,也就是说,同一个模板实例化了许多不同的类型,这会导致同一实体的多个副本出现”

在后一种情况下,较大的可执行文件大小是否会导致软件运行更慢,因为必须将更多的代码加载到内存中,这反过来会导致昂贵的分页

同样,由于这些问题也有一定的编译器依赖,所以我对VisualC++编译器感兴趣。关于大多数编译器所做工作的概括回答也提供了很好的见解


提前谢谢。

它们是否内联始终取决于编译器。对于所有类似的实例化,非内联模板实例化是共享的

因此,许多翻译单元都希望生成一个
Foo
,它们将共享Foo实例化。显然,如果
Foo
是一个函数,并且编译器在每种情况下都决定内联它,那么代码就会重复。然而,选择内联是因为这样做的优化很可能优于函数调用

从技术上讲,模板可能会导致执行速度变慢。我从事的软件具有超紧密的内部循环,我们对其进行了大量的性能测量。我们使用了大量的模板函数和类,与手工编写代码相比,它还没有表现出降级

我不能确定,但我认为您必须有一种情况,即模板: -生成的非内联代码 -对多个实例化执行此操作 -可能是单手写的功能 -手写函数作为一个函数不会导致运行时惩罚(即:没有涉及运行时检查的隐式转换)

然后,您可能会遇到这样的情况:单个手写函数适合CPU的指令缓存,但多个模板实例化不适合

由于模板实体在声明时必须定义(通常是头文件)

不是真的。您可以单独声明和定义模板类、方法和函数,就像您可以声明和定义其他类、方法和函数一样

我有一个想法,我试图说服自己,当一个模板被实例化后,它将被编译器内联,这是错误的。我想问一下,这是不是真的

可能是其中的一部分,或者全部,或者一个也没有。编译器将做它认为最好的事情

编译速度较慢是显而易见的,因为模板必须实例化,但为什么“可能更大的可执行文件”?这应该以什么方式来解释

它可以有多种解释。就像一瓶阿斯匹林含有“可能诱发”的警告一样

我应该将其解释为“许多函数都是内联的”还是“如果有许多模板实例化,可执行文件的大小就会增加,也就是说,同一个模板实例化了许多不同的类型,这会导致同一实体的多个副本出现”

您不会有同一实体的多个副本-编译器套件必须确保这一点。即使方法是内联的,该方法的地址也将:

  • 永远存在,并且
  • 当被多个编译单元引用时,地址必须相同
  • 您可能会发现,您开始创建比预期更多的类型。例如,
    std::vector
    是与
    std::vector
    完全不同的类型
    foo()
    是与
    foo()
    不同的函数。程序中类型和函数定义的数量可以快速增长

    在后一种情况下,较大的可执行文件大小是否会导致软件运行更慢,因为必须将更多的代码加载到内存中,这反过来会导致昂贵的分页


    过度分页,可能不会。很可能是缓存未命中过多。通常,优化较小的代码是实现良好性能的一个很好的策略(在某些情况下,例如当访问的数据很少且都在缓存中时)。

    可以拥有更多代码的一个原因是每种模板类型都有自己的类型。因此,所有关于
    Foo
    的代码都必须在
    Foo
    @NathanOliver中重复,正如我今天了解到的,最新的链接器实现(g++5.x)能够合并回相同的生成实例化代码。@πάνταῥεῖ 你能提供一个链接吗?这听起来很有趣。模板使得决定是否从编译器内联变得很困难。有时候内联是个坏主意,有时候一个好的程序员比一个好的编译器更能判断这种情况。因此,对于模板,程序员通常让编译器内联一些程序员不会决定内联的内容。所以更大(而且由于缓存问题,可能速度较慢)的可执行文件。没有充分的理由,不要认为你比编译器更擅长内联选择。但是