存储三角函数调用的结果是否有意义?

时间:2016-03-05 09:54:11

标签: c++ compilation trigonometry compiler-optimization c++-standard-library

假设我正在编写rotate()库的vector2D方法的实现。

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函数的开销也是多次无效?

2 个答案:

答案 0 :(得分:3)

第一个版本可能是编译器在优化第二个版本时会生成的代码。

有些编译器可能知道sincos是纯函数,它们总是为特定参数返回相同的值。但语言标准对此没有任何说明,所以我们无法确定。

此外,在尝试这样的本地优化之前,您可能会问自己这个函数是否经常被调用,成为应用程序中的瓶颈。如果没有,也许不会注意到确切的速度差异。

gcc编译器将sin和cos映射到__builtin_sin and __builtin_cos,因此它对这些函数有了额外的了解,但我不知道优化器是否会利用它。

答案 1 :(得分:1)

您还可以为vector.x - origin.xvector.y - origin.y定义变量。正如已经说过的那样,这不是性能问题,因为编译器无论如何都会实现这些优化,但是代码可读性问题。

如果您创建这些附加变量,则还应将其声明为const,因为您不打算更改其值。

对于使用这些"冗余"有不同的意见。变量。如果我能为他们找到一个有意义的名字,我个人会使用它们。