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では、externテンプレートを使用できるため、テンプレートのインスタンス化はextern変数と同じように1回だけ行われます。

コンパイラは、テンプレートを表示するたびに引数を使用してテンプレートをインスタンス化する必要がないため、これはコンパイル時に役立ちます。

自分のプロジェクトでこの機能をどのように使用するかはまだ正確にはわかりませんが、コンパイル時間を助けることができるものはすべて私にとってプラスです。

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

于 2011-01-12T11:50:10.187 に答える
1

テンプレートを使用すると、コンパイルとリンクの時間が大幅に増加することがわかりました。問題の1つは、テンプレートを宣言するヘッダーを含む各ファイルがテンプレートを解析し、その有効性を確認する必要があることです。コンパイルユニットで使用される場合、生成されたオブジェクトファイルにはコードが含まれ、後で削除されます。リンカ(複数のファイルで使用される場合)。

私たちのプロジェクトでは、ほとんどすべてのファイルに含まれているいくつかの大きなテンプレートがありましたが、インスタンス化は2つしかありませんでした。明示的なインスタンス化を使用し、テンプレートコードを複数のファイルに分離することで、コンパイル時間を大幅に改善しました。

あなたの例では、それはあなたに与えるでしょう:

// 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 に答える
1

一般に、プログラムをより複雑にする (長くする) と、呼び出しサイトでより多くの曖昧さをなくす必要があるため、コンパイラは速くなるどころか遅くなります。

ただし、そのような特殊化を大量に自動的に生成しない限り、大きな問題にはなりません。また、パフォーマンスはコンパイラーによって異なります。いつでも自分でテストできます (厳格なテストと多数のテスト実行なしでは違いが小さすぎるとは思えません)。

テンプレートが参照されているすべてのコンパイル モジュールでテンプレートが「インライン」と宣言されているため (必ずしもインライン化されているとは限りません)、リンカの速度が低下する可能性があります。これが発生すると、メソッドがいたるところに複製され、リンカーはより多くの作業を行います。比較すると、ヘッダーに宣言があり、定義が 1 つの場所にある「通常の」関数は、コンパイルされた関数が 1 つだけになるため、リンカー (およびコンパイラ) の関数が少なくなります。リンク時のコード生成などのオプションに応じて、これはかなり重要な場合もあれば、ほとんど問題にならない場合もあります。

于 2011-01-12T10:46:38.513 に答える
0

ツールチェーンに厳密に依存します(この場合、少なくともリンカーとコンパイラ、おそらくそれ以上)。

試してみてください。ただし、ツールチェーンの 1 つの部分を変更するだけでも、結果が大きく異なる可能性があることに注意してください。

于 2011-01-12T11:27:13.843 に答える