0

版本 A:

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

版本 B:

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

在性能方面,这两者中哪一个更可取?

备注:

  • 实际代码每秒将使用数百万次,因此性能和速度至关重要。在进行分析之前,您能否给我一些意见,以防我遗漏了什么?

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

4

3 回答 3

3

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

对于琐碎bool的情况(即两者),这无关紧要。

而且,当然,您可以进行分析,但我怀疑这将是一个瓶颈。

于 2013-01-21T15:41:42.983 回答
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;
    

如果 c 不可预测。在这种情况下,您希望将控制流依赖项替换为数据依赖项,该依赖项可以编译为条件移动。当控制依赖性不可预测时,它是净收益。

于 2013-01-21T16:22:25.103 回答
0

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

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

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

这可能是有益的,因为它会为每个 && 替换删除一个分支。 大多数情况下,将几个布尔值“与”在一起比对每个布尔值进行分支要便宜。这适用于任何具有相对昂贵分支的 cpu 架构,即任何具有乱序执行或长指令执行管道(几乎占所有内容)的东西。

重要提示:在 x86 上,条件执行器和分支预测器足够好,如果布尔 A 预测良好(例如,很少更改且预测率高于 99.6%),那么使用 && 形式和捷径实际上更有效的条件。然而,ARM 和 PowerPC 架构几乎总是受益于更少的分支。

于 2013-01-21T21:58:18.903 回答