2012-12-13 105 views
26

我在我的C++項目中有一個粒子系統引擎,粒子本身只是沒有函數的變量結構。目前,每個粒子(粒子)通過直接訪問其變量而從其父類(粒子系統)更新。例如。吸氣劑和固化劑。有沒有性能開銷?

particle.x += particle.vx; 

不過,我使用getter和setter這樣的辯論:

particle.setX(particle.getX()+particle.getVX());

我的問題是:有來自調用getter和setter方法,而不是隻是直線上升的數據的性能開銷訪問?

畢竟,我有很多很多的粒子通過更新...

+1

setter/getter主要用於代碼的可讀性/可維護性。調用一個函數會比直接訪問數據具有更高的性能開銷。 –

+2

獲取者和設置者僅用於封裝數據以及訪問數據。沒有性能開銷,簡單的getter和setter被編譯器內聯。 –

+3

@habeebperwad:我無法想象他們是如何提高可讀性的,但他們當然可以更容易地改變實現方式。 –

回答

39

當未優化時,安裝程​​序和獲取程序的性能開銷爲它們幾乎總是在優化鏈接時間的編譯器上進行優化。對於編譯器,如果他們具有函數體的知識(即不僅僅是原型),它將被優化。

但是,您使用getter和setter,因爲您可能想要獲取或設置該變量以產生其他副作用。就像改變一個物體的位置一樣,它也會改變物理模擬或其他物體中附近物體的位置。

最後,在優化代碼的上下文中,getter和setter操作的開銷非常小,除非代碼很熱,否則不值得擔心。如果它很熱,只需將getter或setter移動到頭文件並內聯即可。因此,總而言之,獲取者和設置者非常值得一些次要的或不存在的開銷,因爲它允許您非常明確地指定對象可以發生和不可能發生的事情,並且還允許您編組任何更改。

+3

+1內聯(儘管其他也是現貨)。內聯和忘記。 – MPelletier

+0

如何優化它?有人爲getters添加const嗎? – sgtHale

+4

但請記住,內聯函數只是a)一個建議,並且b)僅在源文件具有所有可用信息時纔有效,因此它必須位於標題中。 – OmnipotentEntity

4

getter和setter方法讓你的代碼在未來更容易演變,如果獲取和設置練得稍微更復雜的任務。大多數C++編譯器都足夠智能,可以簡化這些簡單的方法,並消除函數調用的開銷。

2

可能有這個問題的各種答案,但我把我的想法放在這裏。

對於性能,對於簡單的POD類型,成本可以大多忽略。 但仍有成本,這取決於你返回的類型。對於粒子,可能不會有太多數據。如果這是一個圖像類(如OpenCV cv :: Mat)或三維數據(如VTK中的PolyData),setter/getter處理指針/迭代器比實際數據更好,以避免內存分配問題。

當你想模板的東西,setter/getter可以是非常有用的,以避免不明確的類型轉換。 setter/getter可以成爲訪問私有/受保護成員的一種方式,這也可以避免使用x作爲變量的通用名稱。更重要的是,setter/getter可以返回一個左值參考,它允許你做particle.getX() = 10.0 ;

+0

particle.getX()= 10.0; - 但是什麼時候需要那個? – SChepurin

+2

@Schepurin當你想要不只是打破封裝,但打破它*可怕* *? –

+0

@MichaelKjörling,我認爲這樣更自然,爲什麼你說它打破封裝? –

14

我有一個不同的觀點比以前的答案。

getters和setters是您的類沒有以有用的方式設計的標誌:如果您沒有從內部實現中創建外部行爲摘要,那麼首先使用抽象接口沒有意義,不妨使用普通的舊結構。

想想你真的需要什麼操作需要。這幾乎可以肯定的是而不是直接訪問位置和動量的x,y和z座標,但您更願意將它們作爲向量(至少在大多數計算中,這與優化有關)。所以你想實現一個基於矢量的界面*,其中的基本操作是向量添加,縮放和內部產品。不是組件式訪問;你可能有時也需要這樣做,但這可以通過一個單獨的std::array<double,3> to_posarray()成員或類似的東西來完成。

當內部組件x,y ... vz無法從外部訪問時,您可以安全地更改內部實現,而無需在模塊外部制動任何代碼。這幾乎是吸氣劑/定型劑的全部重點;然而,在使用這些時,只能進行如此多的優化:任何真正的實現變化都不可避免地使得getters變得更慢。另一方面,您可以使用SIMD操作,外部庫調用(可能在CUDA等加速硬件上)等優化基於矢量的界面。像to_posarray這樣的「批量吸氣器」仍然可以實現合理的效率,單變量安裝人員不能。


*我的意思是在這裏mathematical sense載體,不喜歡std::vector