2

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

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

4 回答 4

2

在 C++0x 中,您将能够使用外部模板,以便模板的实例化只发生一次,就像外部变量一样。

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

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

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

于 2011-01-12T11:50:10.187 回答
1

通过使程序更复杂——更长,并且在调用点需要更多的消歧——通常,编译器会变得更而不是更快。

但是,除非您自动生成大量此类专业,否则这不太可能成为大问题。此外,编译器之间的性能会有所不同——你总是可以自己测试它(我希望如果没有严格的测试和大量的测试运行,差异会太小而不会明显)。

由于模板在引用它的所有编译模块中都被声明为“内联”(尽管不一定是内联的),因此链接器速度可能会降低。发生这种情况时,您将在整个地方复制一个方法,并且链接器会得到更多的工作。相比之下,仅在标头中声明且仅在一处定义的“正常”函数将导致仅编译一个函数,因此链接器(和编译器)的函数更少。根据链接时代码生成等选项,这可能非常重要或根本不重要。

于 2011-01-12T10:46:38.513 回答
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
于 2011-01-12T12:04:18.177 回答
0

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

试一试,但请注意,即使更改工具链的单个部分,结果也可能会有很大差异。

于 2011-01-12T11:27:13.843 回答