编译器会优化这个还是我需要赋值

Would the compiler optimize this or do I need the assignment?

本文关键字:赋值 优化 编译器      更新时间:2023-10-16

如果我在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个字节了——这是在递归方法中。

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

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

——垫

这取决于你用什么选项编译它。通常,即使启用了最小优化的编译器也可以处理这种简单的优化,但是最好还是像在第二段代码中所写的那样自己做。无论如何,如果编译器将优化它,它也将保留additional 4 bytes,因为值需要存储在任何地方。

编译器可能不够聪明,无法意识到powf是无状态的。

当有疑问时,编译成汇编器并自己检查。