执行重复计算

时间:2019-02-17 12:07:49

标签: c++

我想知道值得进行一次计算并存储结果还是进行两次计算更快吗?

例如在这种情况下:

float n1 = a - b;
float n2 = a + b;
float result = n1 * n2 / (n1 * n2);

这样做更好吗?

float result = (a - b) * (a + b) / ((a - b) * (a + b));

? 我知道通常我们会存储结果,但是我想知道执行加法而不是调用内存来存储/检索值不是更快吗。

2 个答案:

答案 0 :(得分:4)

这确实取决于:对于像您这样的琐碎示例,这并不重要。编译器将找到相同的子表达式并消除重复的计算,从而生成相同的代码。

对于更复杂的示例(例如涉及函数调用),最好使用第一个变量来“存储”中间结果。不必担心使用简单变量进行中间存储。这些通常都保存在CPU寄存器中,并且编译器在将值保存在寄存器中方面非常出色。

危险在于,使用更复杂的计算时,编译器可能无法执行常见的子表达式消除。例如,当您的代码包含充当编译器边界的函数调用时,就是这种情况。

另一个主题是,对于浮点数,即使是简单的操作(如加法)也无法关联,即(a + b)+ c与a +(b + c)不同,这是因为最低位的伪像所致。由于不允许编译器更改代码的语义,因此这通常还可以防止常见的子表达式消除。

答案 1 :(得分:0)

将表达式分为较小的表达式并为其赋予明智的名称会为您带来以下好处:

  • 它减少了cognitive load
  • 更长的表达现在可以更容易理解和验证正确。
  • 代码行可能会更短,从而更易于阅读和遵守编码标准。

在C ++中,也可以将临时变量标记为const,这也使编译器可以更好地优化表达式。

但是,在讨论优化并将其用作参数之前,应先对其进行评估。 快速通常来自数据结构和使用的算法的选择。

通常,应编写理解和正确的代码,然后才能对其进行优化。


const float difference = a - b;
const float sum        = a + b;

const float result     = difference * sum / (difference * sum);