2010-10-27 35 views
3

我有一個很基本的問題。DLL的開銷

  1. 當庫僅由單個進程使用時。我應該把它作爲一個靜態庫嗎?
  2. 如果我使用庫作爲DLL,但只有一個進程使用它。 **將會是什麼開銷?*

回答

10

差不多沒有獨立的DLL的開銷。基本上,對從DLL導出的函數的第一次調用將運行一個微小的存根,修復函數地址,以便後續調用通過跳轉表執行一次跳轉。 CPU的工作方式,這種額外的間接性幾乎是免費的。

主要「開銷」實際上是機會成本,而不是「開銷」本身。也就是說,現代編譯器可以做一些名爲「整個程序優化」的工作,在整個模塊(.exe或.dll)中,鏈接時立即編譯和優化整個模塊(.exe或.dll)。這意味着編譯器可以完成整個程序中所有.cpp文件中的調用約定,內聯函數等操作,而不僅僅是在一個.cpp文件中。

這對於某些類型的應用程序可以產生相當好的性能提升。但是,當然,整個程序優化不能跨DLL邊界發生。

+0

不完全正確,通常情況下,函數地址在程序加載時修正,而不是在運行時。關於整個程序優化的評論已經失效,但我還沒有看到任何關於它的真正用處的信息。 – 2010-10-27 05:21:55

+0

@Mark:是的,我可能會考慮延遲加載的DLL ......無論如何,實際開銷本身在任何情況下都很小...... – 2010-10-27 05:29:03

1

導入的函數沒有比虛擬函數更多的開銷。

3

DLL有兩個開銷。首先,當DLL加載到內存中時,內部地址必須針對加載DLL的實際地址與鏈接器所採用的地址進行固定。這可以通過重新構建DLL來最小化。第二種開銷是當程序和DLL被加載時,因爲程序調用到DLL中的函數的地址被填充。除了非常大的程序和DLL之外,這些開銷通常可以忽略不計。

如果這是一個真正的問題,您可以使用延遲加載的DLL,它們只在被調用時才加載。如果DLL從不使用,例如它實現了一個非常罕見的函數,那麼它永遠不會被加載。缺點是第一次調用DLL時會有短暫的延遲。

我喜歡使用靜態鏈接庫,不是爲了減少開銷,而是爲了儘量減少與程序保持DLL的麻煩。