嵌套Ifs VS 2单独的IF - 性能方面?

时间:2013-01-21 15:40:48

标签: c++ performance if-statement

版本A:

if ((A)&&(B)) doSth;
if (B) doSthElse;

版本B:

if (B)
{
    if (A) doSth;
    doSthElse;
}

这两个中的哪一个更适合性能?

注意:

  • 实际代码每秒将使用数百万次,因此性能和速度至关重要。在进行分析之前,如果我遗漏了某些内容,你能不能给我一些意见?

  • 使用-O3在Mac OS X 10.6.8上使用 Clang ++ 编译代码。

3 个答案:

答案 0 :(得分:3)

取决于AB是什么。如果B是一个复杂的函数,第二个只评估它一次,而第一个评估它两次(当然,如果A成立)。

对于琐碎的案例(即两个bool s),无关紧要。

当然,你可以描述一下,我怀疑这将是一个瓶颈。

答案 1 :(得分:2)

假设A和B都是简单的布尔值, 我们需要考虑条件解决的可能性:

  1. 快捷评估:如果(A)可能解析为假而不是(B),则写(A&& B),否则(B&& A)。

  2. 分支可预测性:使用更可预测的条件包围大块。例如,如果B是可预测的,则首选第二种形式。

  3. 尝试将不可预测的条件分配转换为(?:),例如,prefer

    x = c ? a : b; // data dependency
    

    if (c) x = a; // control flow dependency
    else   x = b;
    
  4. 如果c不可预测。 在这种情况下,您希望通过数据依赖项替换控制流依赖项,该依赖项可以编译为条件移动。当控制依赖性不可预测时,它是净增益。

答案 2 :(得分:0)

如果您的A和B值是布尔值,那么我会建议第三个版本:

if (A & B) doSth;
if (B) doSthElse;

此版本使用按位AND来创建多个布尔值的单个比较。这也可以应用于另一个答案中发布的三元运算符解决方案。

这可能是有益的,因为它删除了每个&&和代换。 大多数时候,和几个布林人在一起比在每个人的价值上分支更便宜。这适用于任何具有相对昂贵的分支的cpu体系结构,它可以是无序执行或长指令执行管道(几乎占所有内容)。

重要提示:在x86上,条件执行器和分支预测器足够好,如果布尔A被很好地预测(例如,很少变化并且预测率高于99.6%)那么它实际上更有效地使用&&形式和快捷方式超过条件的其余部分。但是,ARM和PowerPC架构几乎总能从更少的分支中受益。