如果我在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个字节,我会更高兴 - 这是在递归方法中。
答案 0 :(得分:2)
我个人会在这里使用变量。不仅因为它可以提供更好的代码,而且因为它向任何读取代码的人显示值不会改变[我会给它一个比“值”更好的变量名,但是]。我确实希望编译器实际上预先计算该值,但正如已经提到的,它确实依赖于编译器理解powf
是一个纯函数(没有副作用并给出相同的结果)每次输入)。
由于在递归调用中使用额外变量而导致的任何额外存储将是“好的,它应该无关紧要”或“你正在非常接近堆栈溢出的深渊边缘” 。堆栈溢出可能是最糟糕的崩溃类型之一,因为它绝对没有警告或恢复方式,因为程序需要使用堆栈来恢复,它可能是唯一可用的溢出堆栈...如果你的递归函数要么是无界的,要么你无法保证递归调用的数量完全在堆栈的限制内,那么我建议你重新设计这个函数。深度递归通常是非常低效的,以及它容易与stackoverflow崩溃的事实[并且堆栈包含对相同函数的四万次调用,这使得很容易弄清楚它崩溃的原因,但不一定容易弄清楚深度递归的原因]。
- 垫
答案 1 :(得分:1)
这取决于你编译它的选项。通常即使在最小化优化的情况下,编译器也会处理这种简单的优化,但是最好自己动手,就像在第二个代码中编写的那样。无论如何,如果编译器会优化它,它也将保持additional 4 bytes
,因为值需要存储在任何地方。
答案 2 :(得分:0)
编译器可能不够智能,无法实现powf无状态。
如有疑问,请编译成汇编程序并自行检查。