你有它編寫的方式,我期望B::operator*
運行速度稍慢。這是因爲「引擎蓋下」實施A::operator*
是這樣的:
inline A A::operator*(A* this, A b)
{
A out;
out.x = this->x * b.x;
out.y = this->y * b.y;
return out;
}
所以A
將指針傳遞到其左手側參數的功能,同時B
必須使該參數的副本之前調用該函數。兩者都必須複製它們的右側參數。
您的代碼會好得多,而且很可能將實現同爲A
和B
,如果你寫使用引用它,並使它const
正確:
struct A
{
float x, y;
inline A operator*(const A& b) const
{
A out;
out.x = x * b.x;
out.y = y * b.y;
return out;
}
}
struct B
{
float x, y;
}
inline B operator*(const B& a, const B& b)
{
B out;
out.x = a.x * b.x;
out.y = a.y * b.y;
return out;
}
你仍然要返回對象,而不是引用,因爲結果是有效的臨時對象(你沒有返回修改的現有對象)。
附錄
然而,用const傳遞按引用的兩個參數,在B,將它有效地加快使它比A,由於反引用?
首先,當您拼寫出所有代碼時,兩者都涉及相同的解除引用。 (請記住,訪問的this
成員意味着指針引用。)
但即便如此,這取決於你的編譯器是如何聰明的。在這種情況下,讓我們說這看你的結構,並決定,因爲這是兩個浮點數不能塞到一個寄存器,所以它會使用指針來訪問它們。因此,取消引用的指針大小寫(這是實現的引用)是最好的。該組件會是這個樣子(這是僞彙編代碼):
// Setup for the function. Usually already done by the inlining.
r1 <- this
r2 <- &result
r3 <- &b
// Actual function.
r4 <- r1[0]
r4 <- r4 * r3[0]
r2[0] <- r4
r4 <- r1[4]
r4 <- r4 * r3[4]
r2[4] <- r4
這是假設類RISC架構(比如ARM)。 x86可能使用較少的步驟,但無論如何它都會被指令解碼器擴展到這個詳細程度。問題的關鍵是,它的指針的所有固定偏移指針引用寄存器,這是一樣快,因爲它會得到。優化器可以嘗試變得更聰明並在多個寄存器中實現對象,但是這種優化器難於編寫。 (雖然我有心想準是一個LLVM型的編譯器/優化器能做到這一點很容易優化,如果result
僅僅是未保存的臨時對象。)
所以,既然你使用this
,你有一個隱含的指針解引用。但是如果物體在棧上呢?沒有幫助;堆棧變量變成堆棧指針的固定偏移量解引用(或者幀指針,如果使用的話)。因此,除非編譯器足夠亮才能將對象分佈到多個寄存器中,否則您最終會在某處取消引用指針。
隨意將-S
選項傳遞給gcc
以獲取最終代碼的反彙編,以查看您的案例中真正發生了什麼。
你應該閱讀http://stackoverflow.com/questions/4421706/operator-overloading其中顯示技術比任何一個更快。 –