2010-06-24 18 views
0

Virtual functions and performance - C++中所述,虛擬方法可能會影響性能(vtable中的額外查找,不內聯......)。虛擬方法使應用程序變慢,但它們可以加速鏈接嗎?

但我想知道,虛擬功能的使用可以加快鏈接過程嗎?

假設我有一個類X,調用類Y.

  • 的方法,如果該方法是一種非虛方法,然後
    • 編譯器來查找方法類Y來查看它是否有效,以及如何將該調用轉換爲程序集
    • 鏈接器必須在類Y中找到該方法,並用調用方法的地址替換編譯器生成的程序集中的調用地址。
  • 如果該方法是一個虛擬的方法,然後
    • 編譯器也將查找在Y類的方法,並具有查找Y類的虛函數表來構建調用(使用在虛函數表的偏移量)
    • 接頭具有什麼都不做了

在我看來,使用虛擬方法時,鏈接器不會做太多了,和療法之前它會更快(雖然我認爲差異會很小)。

這是真的嗎?有人有這方面的經驗嗎?這是否經過測試?

+13

鏈接時間是否真的很重要? – 2010-06-24 08:57:26

+0

@大衛,有時。如果應用程序變得非常大(並且你不想或不能在多個DLL中分割它),鏈接可能變得非常慢。編譯可以很容易地分佈在一個集羣上(例如使用Incredibuild),但鏈接不能傳播,因此這成爲緩慢的瓶頸。但說實話,我不希望只有使用虛擬方法時鏈接纔會改善超過幾個百分點。 – Patrick 2010-06-24 09:12:28

+0

看到我的回答關於鏈接和動態鏈接的「一次性」成本。如果你喜歡,你可以認爲它是一個O(1)成本鏈接,或O(n)在運行時。 – 2010-06-24 09:29:15

回答

1

我不明白,編譯器是否經歷了與虛擬調用完全相同的過程,而非虛擬調用,只有它必須查找方法將在虛擬表中的位置(以及保持存儲器中的虛擬表,從而破壞了本地化),並處理間接調用的生成代碼?

如果有的話,虛擬調用會減慢編譯時間。

0

不,也不要因爲你給的理由。

在動態鏈接期間可能會節省一些時間,但與虛擬方法的開銷和額外麻煩相比,它可以忽略不計。動態鏈接是一次性成本,虛擬方法會在流程的整個生命週期中花費您的時間。

0

理論上,鏈接器不必爲虛擬函數調用做太多事情。不過,我傾向於懷疑這是否會在實踐中產生很大影響。考慮鏈接器需要做多少工作才能擺脫所有未引用的代碼(這在C++中通常很大)。

如果鏈接時間確實是一個問題,那麼您的努力可能會更好地用於製作DLL /共享庫,而不是靜態鏈接的代碼。

3

軟件的設計不應受編譯或鏈接速度的影響,而應該受常識和針對性的影響!

對不起,如果我在這裏無禮,但試圖贏得幾秒的編譯,以一個可憐的設計爲代價是一個真的不好主意恕我直言。

+0

我完全同意,並且我不打算改變實現只是爲了獲得2秒的鏈接時間。我只是想知道它是否會產生效果。我並沒有考慮這樣做。 – Patrick 2010-06-24 10:02:48

+1

順便說一句,你不粗魯,只是明確:-) – Patrick 2010-06-24 10:04:03

+0

@帕特里克:這很好;)我不想看起來粗魯。 – ereOn 2010-06-24 12:13:07

0

如果類層次很大,鏈接器必須收集構造符號。如果你的類不是多態的,構造函數通常是內聯的,而如果它們是,構造函數總是被髮射出去:它們必須設置虛表等等。

所以你會(稍微)獲得方法很可能是通過設置構造函數和析構函數來抵消。

0

您忘記了鏈接器需要將函數地址放入vtable中,並將vtables放在可執行文件中。

相關問題