有时我声明"一次使用"我的代码中的变量是为了清晰。这是否会显着影响性能,还是编译器可以对其进行优化?
例如,我倾向于这样做:
int minVal = long_arithmetic_expresion();
int maxVal = even_longer_expression();
for (int i = minVal; i < maxVal; i++)
{
// Do stuff not related to minVal or maxVal
}
double part1 = 4*sqrt(something)* ... // Very long thing
double part2 = 5*sqrt(something else)* ... // Very long thing
double interestingValue = part1 / part2; // This is the only interesting variable for later
而不是:
for (int i = long_arithmetic_expresion(); i < even_longer_expression(); i++)
{
// Do stuff not related to minVal or maxVal
}
double interestingValue = (4*sqrt(whatever)* ...) / (5*sqrt(something else)* ...);
这个for循环将包含在一个将被多次调用的函数中,所以即使很小的性能增益也会与我的情况相关。
注意:
正如很快指出的那样,有可能在循环的每一步都可以评估 even_longer_expression(),这当然不是好事。 为清楚起见,我的问题涉及声明一次性变量的事实。 我在循环后添加了一些代码。我指的是变量 part1 和 part2 等案例。
答案 0 :(得分:3)
这是否会显着影响性能,还是编译器可以对其进行优化?
完全取决于:
如果long_arithmetic_expresion()
和even_longer_expression()
标记为constexpr
且在运行时不太可能发生变化,则编译器可以优化对这些函数的重复调用。
否则,最好使用一次初始化的变量。
答案 1 :(得分:1)
除非您禁用优化,否则以下代码几乎肯定会在现代编译器上显示完全相同的性能(假设表达式显然是独立的):
// save to temporary minVal variable
int minVal = long_arithmetic_expresion();
int maxVal = even_longer_expression();
for (int i = minVal; i < maxVal; i++) {
...
}
// avoid creating temporary minVal variable
int maxVal = even_longer_expression();
for (int i = long_arithmetic_expresion(); i < maxVal; i++) {
...
}
但是第一个版本通常更具可读性=)
原因是:基础类型变量的copy propagation对于编译器来说是微不足道的。因此,在第一个版本中,编译器将删除i = minVal
赋值。