编译器会优化这个还是我需要分配?

时间:2013-03-20 19:46:13

标签: c++ optimization

如果我在for循环中有一个方法调用,对于循环的所有迭代都是相同的 - 编译器是否足够智能来优化它?

 for (int j = 0; j < 24; j++ ) {
        *destinationPointer++ = identityArray[j] * (1 / powf(2, valueFromAboveInMethod));
 }     

或者我应该明确并将其分配给循环之前的值吗?

 float value = 1 / powf(2, valueFromAboveInMethod);

 // populate the array
 for (int j = 0; j < 24; j++ ) {
        *destinationPointer++ = identityArray[j] * value;
 }     

如果编译器在这里做了一些非常棒的事情并且我不必使用浮点数的4个字节,我会更高兴 - 这是在递归方法中。

3 个答案:

答案 0 :(得分:2)

我个人会在这里使用变量。不仅因为它可以提供更好的代码,而且因为它向任何读取代码的人显示值不会改变[我会给它一个比“值”更好的变量名,但是]。我确实希望编译器实际上预先计算该值,但正如已经提到的,它确实依赖于编译器理解powf是一个纯函数(没有副作用并给出相同的结果)每次输入)。

由于在递归调用中使用额外变量而导致的任何额外存储将是“好的,它应该无关紧要”或“你正在非常接近堆栈溢出的深渊边缘” 。堆栈溢出可能是最糟糕的崩溃类型之一,因为它绝对没有警告或恢复方式,因为程序需要使用堆栈来恢复,它可能是唯一可用的溢出堆栈...如果你的递归函数要么是无界的,要么你无法保证递归调用的数量完全在堆栈的限制内,那么我建议你重新设计这个函数。深度递归通常是非常低效的,以及它容易与stackoverflow崩溃的事实[并且堆栈包含对相同函数的四万次调用,这使得很容易弄清楚它崩溃的原因,但不一定容易弄清楚深度递归的原因]。

- 垫

答案 1 :(得分:1)

这取决于你编译它的选项。通常即使在最小化优化的情况下,编译器也会处理这种简单的优化,但是最好自己动手,就像在第二个代码中编写的那样。无论如何,如果编译器会优化它,它也将保持additional 4 bytes,因为值需要存储在任何地方。

答案 2 :(得分:0)

编译器可能不够智能,无法实现powf无状态。

如有疑问,请编译成汇编程序并自行检查。