模板类专门化/显式实例化是否提高了编译/链接器速度?

时间:2011-01-12 10:43:49

标签: c++ templates linker compilation specialization

假设以下模板类在大多数 int 作为typename的项目中被大量使用,并且自引入此类以来链接器速度明显变慢。

template <typename T>
class MyClass
{
void Print()
{
    std::cout << m_tValue << std::endl;;
}
T m_tValue;
}

定义一个类专业化的好处编译速度? 例如

template <>
class MyClass<int>
{
void Print()
{
    std::cout << m_tValue << std::endl;;
}
int m_tValue;
}

或者显式实例化是否提供了更好的解决方案? 例如

template class MyClass<int>;

4 个答案:

答案 0 :(得分:2)

在C ++ 0x中,你将能够使用extern模板,这样模板的实例化只会像extern变量一样发生。

这应该有助于编译时间,因为编译器不必每次看到它时都必须使用参数来实例化模板。

我还没有弄清楚我将如何在我自己的项目中使用此功能,但任何可以帮助编译时间的东西对我来说都是一个加分。

http://www2.research.att.com/~bs/C++0xFAQ.html#extern-templates

答案 1 :(得分:1)

通过使程序更复杂 - 更长,并且在呼叫站点需要更多消歧 - 通常,编译器将变得更慢而不是更快。

然而,除非你自动产生大量此类专业,否则它不太可能是一个大问题。此外,编译器之间的性能也各不相同 - 您可以自己进行测试(我预计如果没有严格的测试和大量的测试运行,差异就会太小而无法显现。)

由于模板在所引用的所有编译模块中被声明为“内联”(但不一定是内联的),因此链接器速度可能会降低。当发生这种情况时,您将在整个地方复制一个方法,并且链接器可以获得更多工作。相比之下,只有一个标题中的声明和只有一个位置的定义的“普通”函数将只生成一个编译函数,因此链接器(和编译器)的函数更少。根据链接时代码生成等选项,这可能很重要或根本不重要。

答案 2 :(得分:1)

我们发现模板可以大大增加编译和链接时间。其中一个问题是每个包含声明模板的标头的文件都必须解析它,检查其有效性,如果编译单元使用它,生成的目标文件将包含代码,稍后将通过链接器(如果由多个文件使用)。

在我们的项目中,我们有一些大型模板,几乎包含在每个文件中,但其中只有两个实例存在。通过使用显式实例化以及在多个文件中分离模板代码,我们大大缩短了编译时间。

对于你的例子,那会给你:

// MyClass.h
template < typename T >
class MyClass
{
void Print();
T m_tValue;
}

// MyClass.inl
#ifdef MY_CLASS_METHODS_ARE_NOT_INLINE
#   define MY_CLASS_INLINE
#else
#   define MY_CLASS_INLINE inline
#endif

template < typename T >
MY_CLASS_INLINE void MyClass< T >::Print()
{
    std::cout << m_tValue << std::endl;
}

#undef MY_CLASS_INLINE

// MyClass.cpp
#include "MyClass.h"

#define MY_CLASS_METHODS_ARE_NOT_INLINE
#include "MyClass.inl"

template class MyClass< int >;
template void MyClass< int >::Print();

#undef  MY_CLASS_METHODS_ARE_NOT_INLINE

答案 3 :(得分:0)

它严格依赖于您的工具链(在这种情况下至少链接器和编译器,可能更多)。

试试看,但请注意,通过更改工具链的单个部分,结果可能会有很大差异。