编译器会优化这个还是我需要赋值
Would the compiler optimize this or do I need the assignment?
如果我在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是无状态的。
当有疑问时,编译成汇编器并自己检查。
- 为"adjacent"变量赋值时出现问题
- C++中的赋值发生,尽管右侧出现异常
- 用C++中的sscanf赋值
- 为std::string的某个索引赋值
- 返回值优化:显式移动还是隐式
- 重载Singly Linked List中的赋值运算符
- 为什么我必须在C++中添加一个赋值符号来声明一个数组
- gtest_使用setargpointee在函数中赋值
- 非常量变量只读位置的赋值
- 使用赋值运算符重载从类中返回jobject
- C++数据文件、数组和计算赋值
- 为什么在使用转换构造函数赋值后调用C++类的析构函数?
- 全局作用域中函数指针的赋值
- 错误:在为指针赋值时,void值没有被忽略
- 编译器对initializer_list赋值的优化使程序核心转储?
- 了解工厂方法和静态变量赋值的返回值优化 (Visual Studio)
- 优化向量赋值 c++
- 如果没有定义Move语义(Move构造函数和Move赋值操作符),编译器是否默认优化
- 编译器会优化这个还是我需要赋值
- 优化变量值的重复赋值