2012-04-14 90 views
1

昨天,我被問到一個問題,使用繼承和模板之間的性能權衡是什麼?C++:繼承和模板性能折衷

我說虛擬函數的情況下,動態鏈接會導致一些性能問題,當涉及到繼承。但是,使用模板時,專用類將在編譯時自身生成,因此除了可執行文件的大小隨着特定類的數量增加而增加外,沒有性能問題。

任何人都可以解釋是否有其他事情要考慮嗎?

Thx! 拉胡爾。

+2

不知道如果「動態鏈接」是什麼虛擬函數做的通常術語......當然,我從來沒有聽說過靜態與動態庫和對象文件的上下文之外使用的詞「連接」,所以呃... – cHao 2012-04-14 08:31:05

+5

「動態鏈接」的正確術語是動態綁定或[動態分發](http://en.wikipedia.org/wiki/Dynamic_dispatch),如果我正確理解你描述的內容 – amit 2012-04-14 08:34:38

+0

@amit你是對的 - 你可以檢查這裏的術語:http://www.parashift.com/c++-faq-lite/virtual-functions.html – 2012-04-14 08:35:53

回答

3

首先 - 繼承&模板在我看來是相互正交的(參見OOSC的章節)。在C++中,權衡基本上歸結爲:

  • 模板需要可執行文件中的空間,因爲每個專業 都需要生成代碼。
  • 虛擬函數的繼承需要一個vtable,所有非靜態方法調用都需要一個額外的參數(this)和調用虛擬函數的方式通過vtable進行間接尋址。

所以它的空間與速度。但是你可以在同一個課堂上有兩個好處&(參見我的第一句話 - 這些特徵與他們想要達到的特徵是正交的)。

+0

yes ..這幾乎是我告訴那個人。但他並不太感動。那就是爲什麼我只是想知道當我們談論模板時性能事件是否出現。 – rahul 2012-04-14 08:38:46

1

你說虛擬函數可以有一個性能開銷並且模板實例化有一個代碼開銷,但是兩者都可以被緩解是非常正確的。我一直不得不提醒自己,C++是建立在不支付你不使用的東西的前提下的,所以對於繼承類,你總是可以將普通代碼移動到非虛函數中以避免虛表查找,有時使內聯方法可以很好地發揮編譯器的優化功能,並使代碼更快(無函數調用),並且更小。

與模板類似,任何不依賴於模板類型的代碼都可以推送到非模板基類中,因此只會有一個函數副本。