假设以下模板类在大多数 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>;
答案 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)
它严格依赖于您的工具链(在这种情况下至少链接器和编译器,可能更多)。
试试看,但请注意,通过更改工具链的单个部分,结果可能会有很大差异。