2011-01-25 72 views
1

比较两种:我应该在`else if`中删除不必要的`else`吗?

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进行预解码。在第二种情况下,直到B1被评估为假时,它才会解释B2。

我发现了很多(也许大多数?)源使用后者的形式。 尽管后一种形式看起来更好理解,因为它不是很明显,只有在没有else子句的情况下a =~ /ear(?!th)/才会调用return y

+0

会编译器确实产生第二个片段?我会怀疑它。 – asveikau 2011-01-25 09:12:29

+0

你为什么从你的代码中删除回报?这是完全改变的问题? – UmmaGumma 2011-01-25 10:04:41

+3

当已经有答案发布到以前的版本时,进行编辑可以大大改变问题的含义,这是非常令人困惑的。即,它使这些答案不正确。 – 2011-01-25 10:09:31

回答

6

你的编译器可能知道这两个例子意味着完全一样的东西。 CPU分支预测不会进入它。

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

0

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

例如与你那里的确切条件的情况下,让我们说= -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 
2

使用else if状态你的意图明确。代码旨在被读取。

让编译器优化它,直到你的代码是1)工作2)水晶般清除3)profiled(按照这个顺序)。在执行第3步时,您会注意到瓶颈不在您所期望的位置。

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

看看基于LLVM的编译器的输出,看看我的意思:有时甚至不能远程理解它的功能。

3

如下回答的问题。的原始版本)

你是否意识到,这两个代码片段都没有语义上等同???

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

  • 第一个片段调用foo(),然后bar()
  • 第二个片段调用foo()并跳过bar()调用。

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

就个人而言,我觉得别人是多余的...

不幸的是,你的感觉是不正确。教程 - 简单明了地编写代码,并将优化留给编译器......这将比你做得更准确的工作。


随访

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

  • 任何像样的优化编译器将产生两个片段相同的代码,并
  • 这是见仁见智的问题(即主观)该片段的更容易理解。
0

为什么不干脆写

char* str; 

strstr(a, "ear") 

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

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