【问题标题】:Should variable declarations always be avoided in C++?在 C++ 中是否应该始终避免变量声明?
【发布时间】:2016-01-12 02:49:48
【问题描述】:

为了清晰起见,有时我会在代码中声明“一次性”变量。这会显着影响性能还是编译器可以对其进行优化?

例如,我倾向于这样做:

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() 有可能在循环的每一步都被评估,这当然不好。 为了清楚起见,我的问题与声明一次性变量的事实有关。 我在循环之后添加了更多代码。我指的是变量 part1part2 之类的情况。

【问题讨论】:

  • 在您的示例中,仅应声明 int maxVal = even_longer_expression();
  • even_longer_expression() 将在每次通过时都被评估,所以当然不把它放在那里是有意义的。
  • minValmaxVal 应该是 const 甚至 constexpr 如果可能的话。它不仅可以防止您意外更改它们的值,还可以提示编译器进行更多优化。
  • 我认为您真正想要的示例是循环条件是大型算术表达式,不会随着迭代而改变。最好用这样一个例子来编辑问题。

标签: c++ performance readability variable-declaration


【解决方案1】:

这会显着影响性能还是编译器可以优化它?

完全取决于:

如果 long_arithmetic_expresion()even_longer_expression() 被标记为 constexpr 并且在运行时不太可能发生变化,编译器可以优化对这些函数的重复调用。

否则最好使用一次初始化的变量。

【讨论】:

  • 另外将maxVal 设为const。那么,这也是迭代器末端的传统风格。它可以轻松地防止对 for 循环的每次迭代进行重新评估。
  • @B98 简而言之,这是否意味着如果它们是const,则在声明额外变量时没有性能损失,但如果它们不是const,最好避免额外声明?
  • @frischkase 取决于编译器和开关,但我认为const 可能会增加触发优化的机会,但不声明变量并将大量代码集中在一起看起来像是过早的优化。如果需要,只有目标代码会揭示实际需求,但今天的优化器确实遵循流程并进行优化。const 和变量都引入了可以表达意图的 names 或缩写 const将 const-ness 添加到含义中。我认为在这种情况下,性能不是主要问题,可能是逻辑和风格。
【解决方案2】:

除非您禁用优化,否则以下代码几乎肯定会在现代编译器上显示完全相同的性能(假设表达式显然是独立的):

// 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 赋值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-17
    • 2016-03-16
    • 1970-01-01
    • 1970-01-01
    • 2011-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多