0

假設我正在寫一vector2D庫的rotate()方法的實現。存儲三角函數調用的結果是否有意義?

vector2D rotate(const vector2D vector, const vector2D origin, float radians) 
{ 
    // Implementation details 
    return {x, y}; 
} 

我可以存儲三角函數的結果調用的變量,所以我不必多次打電話給他們:

float sr = sin(radians); 
float cr = cos(radians); 
float x = origin.x + (
    (vector.x - origin.x) * cr - (vector.y - origin.y) * sr 
); 
float y = origin.y + (
    (vector.x - origin.x) * sr + (vector.y - origin.y) * cr 
); 

或者,我可以簡單的寫了我的意思

float x = origin.x + (
    (vector.x - origin.x) * cos(radians) - (vector.y - origin.y) * sin(radians) 
); 
float y = origin.y + (
    (vector.x - origin.x) * sin(radians) + (vector.y - origin.y) * cos(radians) 
); 
  • 這些情況的優缺點是什麼?
  • 編譯器是否優化了第二個示例中的開銷?或者,即使在vector2D庫的情況下,調用trig函數的開銷多少也不明顯?

回答

3

第一個版本可能是編譯器在優化第二個版本時生成的代碼。

某些編譯器可能知道sincos是純函數,它們始終爲特定參數返回相同的值。但語言標準對此沒有提及,所以我們不能確定。

此外,在嘗試像這樣的本地優化之前,您可能會問自己是否經常調用此函數以成爲應用程序的瓶頸。如果不是,也許不會注意到確切的速度差異。

gcc編譯器將sin和cos映射到__builtin_sin and __builtin_cos,所以它對這些函數有更多的瞭解,但我不知道優化器是否會利用這些功能。

+0

gcc編譯器將sin和cos映射到['__builtin_sin'和'__builtin_cos'](https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html),因此它具有這些函數的其他知識,但我不知道優化器是否會利用這一點。 –

+1

GCC不僅可以保存sin/cos的結果,而且可以同時計算[兩者同時](http://goo.gl/fkSLcf)。 Clang並不那麼尖銳,可悲。另一件要考慮的事情是:如果你在雙打中進行計算,則會產生更少的代碼。 –

+0

@Revolver_Ocelot'雙打計算'是什麼意思? 「雙打」作爲第二個例子中的重複代碼? – sjaustirni

1

您也可以定義變量vector.x - origin.xvector.y - origin.y。如前所述,這並不是性能問題,因爲編譯器無論如何都會實現這些優化,而只是代碼可讀性問題。

如果您創建這些附加變量,則還應聲明它們爲const,因爲您不打算更改它們的值。

有關於如何使用這些「冗餘」變量不同的意見。我個人會使用它們,如果我能找到一個有意義的名字。

+0

非常好的評論,但不完全是問題的答案。您能否將其作爲評論發佈? – sjaustirni

+0

@Dundee:不確定,你一直在尋求優點和缺點,我認爲我在現有答案中增加了一些其他方面。 –

+0

的確如此。我在使用trig函數時想要利弊,但沒有說清楚。無論如何,我現在不會改變它,所以這應該留下來作爲答案。 – sjaustirni