2017-07-28 5 views
2

Beispiel: sagen, dass ich in meiner vorkompilierte Header-Datei:Wird die Instanziierung von Vorlagen in vorkompilierten Headern die Kompilierzeit reduzieren?

#include <vector> 

Als wenige Fälle des Vektors, wie std :: vector, std :: vector usw. werden oft in meinem Projekt verwenden, wird es reduce kompilieren Zeit, wenn ich sie auch in der precomiled Header wie folgt instanziiert:

#include <vector> 
template class std::vector<float>; 
template class std::vector<int>; 

weiter gehen, wird es sinnvoll, auch Dummy-Funktionen auf die vorkompilierte Header hinzufügen, die einige Funktionen verwendet:

namespace pch_detail { 
inline auto func() { 
    auto&& v = std::vector<float>{}; 
    v.size(); 
    v.begin(); 
    v.front(); 
} 
} 

Ich bin mir sehr unsicher, wie Übersetzungseinheiten und Templates wirklich funktionieren, daher scheint es mir, wenn ich sie in den vorkompilierten Headern instanziiere, dass sie nicht für jede CPP-Datei instanziiert werden müssen.

aktualisieren

auf einer realen Code-Basis Getestet mit Visual Studio 2017 und einigen Umschreibungen Template-Klassen verwendet.

  1. Mit gemeinsamer Templat Klasse instanziiert: 71731 ms
  2. Ohne Instanziierung: 68544 ms

daher zumindest in meinem Fall dauerte es dauerte etwas mehr Zeit.

+0

Ist Zeit wirklich ein Problem, das Sie lösen müssen kompilieren? Das letzte Mal, dass ich so ein Problem hatte, war ungefähr 1993. – EJP

+0

Ja, es ist, und es war in jeder Firma, in der ich jemals gearbeitet habe. Und auch jede Firma, die C++ benutzt, von der ich schon gehört habe. –

Antwort

3

Es kann einen Unterschied ja machen.

Instanziierung in Übersetzungseinheiten kann dann Daten im vorkompilierten Header ausnutzen, und ein Compiler kann das schneller lesen als die Header der C++ - Standardbibliothek.

Sie müssen jedoch eine Liste von Instanziierungen verwalten, sodass diese Kompilierungsoptimierung möglicherweise mehr Probleme verursacht als es wert ist - Ihre Idee könnte den gegenteiligen Effekt haben, wenn Sie Instanziierungen durchführen, die nicht mehr benötigt werden.

3

Komisch, aber zumindest für clang (4.0.1) Ihre Variante Erhöhung der Kompilierung:

1. no pch 

real 0m0,361s 
user 0m0,340s 
sys  0m0,021s 

2. pch, no explicit instantiate 

real 0m0,297s 
user 0m0,280s 
sys  0m0,017s 

3. pch, explicit instantiate 

real 0m0,507s 
user 0m0,474s 
sys  0m0,033s 

Ich benutze einen solchen Code:

#include <iostream> 
#include "test.h" 

int main() { 
     std::vector<float> a = {1., 2., 3.}; 
     for (auto &&e : a) { 
       std::cout << e << "\n"; 
     } 
     std::vector<int> b = {1, 2, 3}; 
     for (auto &&e : b) { 
       std::cout << e << "\n"; 
     } 
} 

Fall 2 test.h

Fall 3

#pragma once 

#include <vector> 
template class std::vector<float>; 
template class std::vector<int>; 

und solche Kompilation Skript:

echo "no pch" 
time clang++ -std=c++11 main.cpp 

echo "pch, no explicit instantiate" 
clang++ -std=c++11 -x c++-header test.h -o test.pch 
time clang++ -std=c++11 -include-pch test.pch main.cpp 

echo "pch, explicit instantiate" 
clang++ -std=c++11 -x c++-header test2.h -o test2.pch 
time clang++ -std=c++11 -include-pch test2.pch main2.cpp 
+0

Eine einmalige Verwendung eines vorkompilierten Headers ist ein Missbrauch der Idee, aber dies ist eine gute Analyse. Habe eine Verbesserung! – Bathsheba

+0

Aber was ist, wenn Sie 1000 verwenden.CPP-Dateien? –

+0

@ViktorSehr Das Kompilieren von '.cpp' Dateien ist ein separater Prozess, also multipliziere einfach die Zahl auf' 1000', dividiere die Anzahl der Kerne und du bekommst Zahlen. – fghj

Verwandte Themen