2011-01-12 5 views
2

Angenommen, die folgende Template-Klasse wird in einem Projekt mit int als Typname und Linker-Geschwindigkeit ist seit der Einführung dieser Klasse deutlich langsamer verwendet.Verbessert Template-Klassenspezialisierung/explizite Instanziierung die Compiler-/Linker-Geschwindigkeit?

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

Definiert eine Klassenspezialisierung die Kompilierungsgeschwindigkeit? z.

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

Oder bietet explizite Instanziierung eine bessere Lösung? z.

template class MyClass<int>; 
+0

@sbi, Sie sind richtig, danke, habe ich meine Antwort bearbeitet, können Sie neu bewerten, deren Korrektheit? – Stormenet

+0

Okay, ich hätte sagen sollen, dass ich meine * Frage * bearbeitet habe, nicht meine Antwort;) – Stormenet

Antwort

2

in C++ 0x können Sie externe Vorlagen verwenden, so dass die Instanziierung von Vorlagen nur einmal wie externe Variablen erfolgt.

Dies sollte bei der Kompilierung helfen, da der Compiler die Vorlage nicht jedes Mal mit ihren Argumenten instanziieren muss, wenn sie sie sieht.

Ich habe noch nicht herausgefunden, genau, wie ich diese Funktion in meinen eigenen Projekten verwenden werde, aber alles, was helfen kann, Zeiten zu kompilieren, ist ein Plus für mich.

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

1

Indem das Programm komplex - mehr und mehr Begriffsklärung in einer Call-Site erforderlich - in der Regel wird ein Compiler wird langsamer nicht schneller.

Es ist jedoch wahrscheinlich kein großes Problem, es sei denn, Sie generieren automatisch eine große Anzahl solcher Spezialisierungen. Außerdem variiert die Leistung zwischen den Compilern - Sie können sie immer selbst testen (ich erwarte, dass der Unterschied zu gering ist, um ohne rigorose Tests und eine große Anzahl von Testläufen erkennbar zu sein).

Es ist möglich, die Linker-Geschwindigkeit zu reduzieren, da die Vorlage in allen Kompilierungsmodulen, in denen sie referenziert wird, als "Inline" deklariert wird (obwohl sie nicht unbedingt inline sind). Wenn das passiert, duplizierst du eine Methode überall und der Linker bekommt mehr Arbeit. Im Vergleich ergibt eine "normale" Funktion mit nur einer Deklaration in einem Header und der Definition in nur einer Stelle nur eine kompilierte Funktion und somit weniger Funktionen für den Linker (und den Compiler). Abhängig von Optionen wie Link-Time-Code-Generierung könnte das ganz oder fast egal sein.

0

Es hängt ausschließlich von Ihrer Toolchain ab (in diesem Fall mindestens Linker und Compiler, vielleicht mehr).

Versuchen Sie es einfach, aber beachten Sie, dass die Ergebnisse sehr variieren können, wenn Sie nur ein einzelnes Teil Ihrer Toolchain ändern.

1

Wir fanden, dass Vorlage, um die Zusammenstellung und Link Zeit stark erhöhen kann. Eines der Probleme ist, dass jede Datei, die den Header enthält, der die Vorlage deklariert, sie analysieren muss, ihre Gültigkeit prüfen muss, und wenn sie von der Kompilierungseinheit verwendet wird, enthält die erzeugte Objektdatei den Code, der später von entfernt wird der Linker (falls von mehr als einer Datei verwendet).

In unserem Projekt hatten wir einige große Vorlagen, die in fast jeder Datei enthalten waren, von denen aber nur zwei Instanzen existierten. Durch die explizite Instanziierung und die Trennung des Vorlagencodes in mehreren Dateien wurde die Kompilierungszeit erheblich verkürzt.

Für Ihre exemple, dass würden Sie:

// 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 
Verwandte Themen