2009-09-08 62 views
0

增強型岩石,它非常棒,功能非常強大,但每當我在Visual Studio 7.1中構建解決方案時,我討厭它。在VS中構建增強型解決方案

看來Boost已經影響了構建時間(不是正向)。我無法從我的項目中刪除所有Boost用法來比較構建時間,但我在小型項目上嘗試過,差別很有意義。

我想問題是,Boost由成千上萬的頭文件組成,其中包含了非常廣泛的內容。所以,當我在我的頭文件中包含boost/function.hpp時,可能會導致包含數百個Boost頭文件。

有沒有經歷過相同的人?任何想法如何解決它?

粗糙的想法:

  1. 添加提振預編譯頭?至少他們將被解析並保存在一個文件中
  2. 爲某些Boost模板做明確的瞬時化?
  3. 以某種方式準備Boost標頭?
  4. 不包括加速至頭文件(聽起來不真實的)
  5. ...

PS。是的,Boost也使用了我認爲很難編譯的硬核模板,所以成千上萬的頭文件不是唯一的問題。

回答

2

當然,包括升壓導致更長的編譯時間 - 就像包括任何庫一樣。由於所有邏輯都是在頭文件中實現的,因此(主要是)模板庫的性能會導致相當大的性能損失。

  1. 我已經有了很好的結果,其中包括預編譯頭文件(的子集)。不過,我相信MSVC 9的收益最大。在MSVC 7上,我看到一些報告稱模板的預編譯頭文件經常導致性能損失。確定您是否會看到性能提升的另一個關鍵方面是在預編譯頭文件中包含適當的頭文件。只包含您經常使用的標題,並確保它們永不改變(即在將您自己的標題添加到此處之前,請考慮三次)

  2. 我不知道明確的瞬時化是否有任何效果,即使我懷疑它。如果任何人都看到了這個結果(無論編譯器),那將是非常有趣的。

  3. 「準備」提升標題聽起來像改變它們,這聽起來對我來說是一個非常糟糕的主意。你不想最終維護定製的標題...

  4. 可能不是你想象的那麼虛幻。儘可能使用盡可能多的forward declarations以減少每個頭文件的「佔用空間」。考慮使用Pimpl模式來避免包含未在您的類的公共接口中反映的增強標題(offtopic:我認爲Pimpl經常是不必要的,相反,我嘗試將這些類切分爲更小的片段,在「更乾淨「的時尚)。只要你在這些類的用法上保持一致,不要害怕包括一般的普通類(例如shared_ptr)(如果你在所有的類中使用它們,你不會看到太多的好處將它們從一個標題中隱藏起來) 。

  5. 升級MSVC(支持並行構建)將有所幫助。但是,這在C++中一直是個問題。爲了最大限度地減少問題,您需要非常嚴格,並遵循指導方針來減少標題的佔位面積。現在,您應該仔細查看包含子句,並確保沒有不必要的內容。如果你的頭文件列表中包含的內容越來越長,那麼你可能會做一些錯誤的事情 - 大部分都應該包括,只有位於cpp中。

0

正如你在你的文章中提到的那樣,boost代碼包含很多模板代碼,需要很多CPU週期才能編譯。相比之下,多頭文件的開銷非常小。

您需要做的第一件事是找出哪個頭文件或哪行代碼負責編譯的延遲。通常不是包含頭文件,而是在其自己的代碼中使用其中一個類/函數,導致延遲。你可以通過註釋掉你的代碼,直到編譯再次快速,然後取消註釋你的代碼塊,直到編譯再次變慢爲止,來分離出負責任的代碼。然後,您可以決定是否要用其他方法替換慢速代碼。您可以權衡這裏的優點和缺點,或者編譯速度與漂亮的提升代碼。

還有一些其他的東西,你可以做的一樣好:

  • 清理不需要的包括語句,尤其在你的頭在你的頭文件
  • ,更換包括前向聲明(如果可能)
  • 獲得更快的計算機:d
+0

看來它不會對我有用。我們已經使用非常快的計算機,但構建過程需要幾個小時......以及如何自動「找出哪個頭文件或哪行代碼負責編譯的延遲」? Codebase非常龐大。 – bocco 2009-09-09 05:33:15

+0

你有這個答案的任何基礎?這似乎違反直覺,簡單的測試(從一個空的main()開始,然後從STL零碎添加包含)表明包含一個文件具有非常實際的成本。我錯過了什麼?謝謝! – 2009-09-13 05:34:12

+0

我不否認包括文件有成本。但是,根據我的經驗,有時使用某些升級代碼的成本會高於包含本身。 – StackedCrooked 2009-09-13 12:16:06

0

包括升壓頭文件只有當他們真正需要的是有道理的。包含其他頭文件的頭文件會對IO造成壓力,並對編譯時間產生很大影響。前向聲明有助於某些觀點,但通過Boost,它可能是真正的痛苦。

在頭文件中使用外部防護可避免不必要的加載。就像這樣:

#ifndef BOOST_SHARED_PTR_HPP_INCLUDED 
# include <boost/shared_ptr.hpp> 
#endif 

另一種方式,以避免頭級聯使用"pimpl"-idiom,尤其是在複雜的類的時候。然後可以包含複雜的Boost內容,並僅由該編譯單元使用。缺點是界面應該設計成不需要Boost特定的東西。但是,打破依賴也可能是一件好事。

+0

如果不是你的代碼,外部包含警衛可能會有風險 - Boost會保證他們不會改變包含警衛的格式嗎? – 2009-09-13 05:24:39

+0

是的。他們可能有風險。有時即使是你自己的代碼。 :) 據我所知,並不能保證Boost的頭部守衛會保持那樣。但是,我願意冒這個風險。如果它們發生變化,那只是一堆編譯器錯誤,可以很容易地指向不包含的文件。 – Virne 2009-09-13 17:47:47

+0

要麼是這樣,要麼是因爲當實際的(爲了參數的緣故)名稱是BOOST_SHAREDPTR_INC時檢查了BOOST_SHARED_PTR_HPP_INCLUDED,並且你的構建突然慢一點,所以你的優化方案被無聲地破壞了。 – 2009-09-14 04:52:48

8

我想也助推了不少

  • 使用預編譯的頭就像你告訴(帶來最)
  • 當使用鏈接庫檢查,如果你真的需要他們(聯也很慢)

另一個也許愚蠢的暗示,但性能損失的本機上的主要來源:

  • 檢查,如果您的防病毒,使按訪問掃描並禁用它頁眉&源目錄(升壓和你的項目)
+2

大拇哥爲防病毒筆記!它們通常造成比病毒更多的傷害。 – Virne 2009-09-08 21:55:15

+0

反病毒之前打過我。 – 2009-09-08 23:08:57

+0

有關防病毒的好處,但已爲構建目錄禁用。我們還爲項目文件和輸出使用單獨的HDD。它有很多幫助。 – bocco 2009-09-09 05:26:23