2017-07-28 111 views
2

例子: 說我包括我的預編譯頭文件:在預編譯頭文件中實例化模板會減少編譯時間嗎?

#include <vector> 

作爲載體的少數情況下,如性病::載體,性病::向量等等都在我的項目經常使用,將它減少編譯時間,如果我在這樣的precomiled頭實例他們還有:

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

的進一步深入,將是有意義的,即使添加的虛擬功能,它使用的一些功能的預編譯的頭:

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

我很不確定翻譯單元和模板是如何工作的,所以在我看來,如果我在預編譯的頭文件中實例化它們,它應該表示它們不需要爲每個.cpp文件實例化。

更新

測試在使用V​​isual Studio 2017年真實世界的代碼庫和常用模板類的一些實例。

  1. 與普通模板類實例化:71731毫秒
  2. 沒有實例:68544毫秒

因此,至少在我的情況下,花了稍微花更多的時間。

+0

是編譯的時候真的是你需要解決的一個問題?上次我遇到這樣的問題大概是在1993年。 – EJP

+0

是的,它曾經在我曾經工作過的每家公司都有過。還有我聽說過的所有使用C++的公司。 –

回答

3

它可以有所作爲是的。

翻譯單元中的實例可以利用預編譯頭中的數據,而編譯器可以比C++標準庫頭更快地讀取數據。

但是你將不得不維護一個實例化列表,所以這個編譯時優化可能比它的價值更麻煩 - 如果你有不再需要的實例化,你的想法最終會產生相反的效果。

3

有趣的事情,但至少clang(4.0.1)的變種增加編譯時間:

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 

我用這樣的代碼:

#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"; 
     } 
} 

情況下2 test.h

#pragma once 

#include <vector> 

案例3

#pragma once 

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

和彙編等腳本:

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

一次性使用預編譯頭是對這個想法的濫用,但這是一個很好的分析。有一個upvote! – Bathsheba

+0

但是如果你使用1000。cpp文件? –

+0

@ViktorSehr編譯'.cpp'文件是一個獨立的過程,所以只需在'1000'上乘以數字,除以核心數量就可以得到數字。 – fghj