簡體   English   中英

傳遞引用的開銷是多少?

[英]what is the overhead of passing a reference?

當有問題的getter返回引用時訪問成員變量有多貴?

例如,如果你有一個需要經常使用這種訪​​問器的類,那么將所述引用存儲在需要使用它的類中並簡單地初始化一次會有多高效?

獲取函數通常不應返回引用。 這樣做的原因是它使該成員對公眾開放 - 如果你想這樣做只是讓它成為一個公共成員。

class foo {
  int bar;
  public:
    int& get_bar() { return bar; } // this is silly! Just make bar public!
}

無論如何,如果它像get_bar一樣簡單,它將被內聯到類似於foo.bar 正如Oli指出的那樣,你也可以將它作為const引用,盡管對於像int這樣的小類,你應該繼續並按值返回。

對於更昂貴的類型,參考開始是有益的。 你可以假設:

  • 價值的“開銷”基於您返回的大小
  • 參考的“開銷”基於參考的大小和解除引用的成本

例如:

foo x;
x.get_value().func(); // calls copy constructor at least once and destructor
x.get_reference().func(); // may require dereference when using

關於復雜性,返回或傳遞引用就像傳遞指針一樣。 它的開銷相當於傳遞一個指針大小的整數,加上一些指令 簡而言之,幾乎在所有情況下都盡可能快。 小於或等於指針大小的內置類型(例如int,float)是明顯的例外。

在最壞的情況下,傳遞/返回引用可以添加一些指令或禁用某些優化。 這些損失很少超過按值返回/傳遞對象的成本(例如,調用復制構造函數+析構函數要高得多,即使是非常基本的對象)。 除非每條指令都有效,否則通過引用傳遞/返回是一個很好的默認值,並且您已經測量了這種差異。

因此,使用引用具有令人難以置信的低開銷。

如果不知道類型及其構造函數/析構函數的復雜性,就無法真正量化它速度,但如果它不是內置類型,那么在大多數情況下,持有本地並通過引用返回它將是最快的 -這一切都取決於對象及其副本的復雜程度,但只有令人難以置信的微不足道的對象才能接近引用的速度。

如果函數定義可用並且相對簡單,那么這樣的函數將被內聯,並且與直接訪問成員相比沒有任何開銷。 否則,操作序列就像獲取地址類/結構對象,應用偏移量來獲取成員的地址,以及將此地址返回給調用者一樣簡單。 現在,對於這些情況,僅當對象是不可復制的或者其大小大於指針的大小時才通過引用返回是有意義的。 不可復制對象的原因是顯而易見的,否則你會看到復制開銷 - 結構的大小與指針的大小。 所以經驗法則是這樣 - 通過引用(或指針)返回大對象,通過復制它們返回小對象(整數,雙精度等)。 在那些您無需控制成員訪問權限的情況下 - 只需使用具有公共訪問權限的成員的結構,並且不要使用大量的getter和setter來破壞您的代碼。

坦率地說,如果你開始想知道這個開銷:你有沒有想過調用約定,使用stdcall而不是cdecl?

你從中獲得的速度類似於你在討論時所說的速度。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM