我应该删除`else if`中不必要的`else`吗?

时间:2011-01-25 08:54:20

标签: c

比较两者:

if (strstr(a, "earth"))     // A1
    return x;
if (strstr(a, "ear"))       // A2
    return y;

if (strstr(a, "earth"))     // B1
    return x;
else if (strstr(a, "ear"))  // B2
    return y;

就个人而言,我觉得else是多余的,并且阻止CPU进行分支预测。

在第一个中,当执行A1时,可以预解码A2。在第二个中,它将不会解释B2,直到B1被评估为假。

我发现使用后一种形式的很多(可能是大多数?)来源。 虽然,后一种形式看起来更好理解,因为只有return y没有else子句才会调用a =~ /ear(?!th)/

5 个答案:

答案 0 :(得分:6)

您的编译器可能知道这两个示例的含义完全相同。 CPU分支预测没有进入它。

我通常会选择对称的第一个选项。

答案 1 :(得分:3)

以下回答问题的原始版本。

你是否意识到这两个代码片段在语义上并不等同?

考虑如果a是“地球”会发生什么。

  • 第一个代码段调用foo(),然后调用bar()
  • 第二个代码段调用foo()并跳过bar()来电。

这解释了为什么生成的机器代码不同。它必须是实现相应代码片段的不同语义!

  

就个人而言,我觉得其他方面是多余的......

不幸的是,你的感觉不正确。

课程 - 简单明了地编写代码并将优化留给编译器......这样做的工作要比你能做到的更准确。


<强>后续

问题的更新版本中的片段现在在语义上相同,else是多余的。但是:

  • 任何一半不错的优化编译器都会为这两个片段生成相同的代码,
  • 这是一个意见问题(即主观),哪些片段更容易理解。

答案 2 :(得分:2)

使用else if 清楚地表明您的意图。代码应由读取。

让编译器对此进行优化,不要担心优化,直到你的代码为1)工作2)清晰3)profiled(按此顺序执行此操作)。在执行第3步时,您会注意到瓶颈不在您认为的位置。

任何控制分支预测或任何低级别内容的尝试都是愚蠢的:编译器非常擅长优化,他们使用复杂的方法在您的特定机器上生成快速代码。

查看基于LLVM的编译器的输出,看看我的意思:有时你甚至无法远程理解它的作用。

答案 3 :(得分:0)

通常最好使用第二种方法,如果你想准确测试a的条件,对于精确的解决方案,减少var或const“a”的选项。如果你写两个单独的if,你可以得到2个不同的解决方案。

例如在你的情况下,你有确切的条件,让我们说a = -2

A: if (a < 0)
    return x; // if -2 is less than 0 will return x and it stops.
else if (a < 100)
    return y; // 

B: if (a < 0)
    return x; // -2 is less than 0 so it will return x and passes to the next if statement;
 if (a < 100)
    return y; // -2 is also less than 100 and it will return y too

答案 4 :(得分:0)

为什么不简单地写

char* str;

strstr(a, "ear")

if (str != NULL)
{
  foo();

  if(strstr(str, "earth") != NULL)
  {
    bar();
  }
}