C ++有条件的经营者业绩(C++ Conditional operator performance

2019-09-22 10:27发布

我有一个条件语句expensive_foo()这是在99.9%的情况下,假的。 我有一个条件语句bar这是〜50%的情况属实。

我想如果两个陈述是真实的一些动作来完成。 所以,我几乎可以肯定知道, expensive_foo()是假的,我要检查它只有bar是真实的。

将下面的代码检查expensive_foo()仅当bar是真的吗? 或者,它会检查expensive_foo()每一次?

if ( bar && expensive_foo() )
{
    ...
}

或者,我需要做的结构是这样的:

if ( bar )
{
    if ( expensive_foo() )
    {
        ...
    }
}

Answer 1:

的逻辑AND运算符&&是短路的,这意味着它是保证第二操作数被评估当且仅当第一个是作为评价true 。 的条件if (bar && foo)if (bar) if (foo)是相同的。

鉴于foo是计算昂贵的,你应该几乎可以肯定检查bar第一。 尽管bar将不直接由分支预测器预测的非常好,这是比较的计算的影响很小foo

因此,结构也许应该是:

if (bar)
{
    if (bool const foo = compute())   // expensive
    {
        // ...
    }
}

请注意,所有这些结构的意味着我们可能会或可能不会调用compute() 如果您需要的函数调用无条件地,那么你应该让第一次检查。 在这种情况下,结果成功的分支预测应该加以利用。



Answer 2:

这两种代码将检查foo只有在案件bar是真实的。 在第一种情况下,这是由语言懒布尔表达式的评估保证(这实际上可以在一些编译器可以明确地关闭,但在缺省情况下)。



Answer 3:

其他答案是好的,但我质疑的前提。

如果您正在查询谓词那是假的99.9%,这是类似于2000个条目,在那里你正在寻找的项目可以用大致相同的概率在任何地方的清单做线性搜索。

在这种情况下,一般人会试图组织名单不同,从而做一个O(logN)的(或更好)搜索,而不是O(N)。 我不知道,如果你能做到这一点,但是这是在那里我会关注的焦点。

当被要求与高度倾斜概率的问题,那可能是一个很大的速度提升的机会,如果能取消扭曲它。 (假设对时间的巨大%,在本次活动中度过的。如果不是这样,就变得毫无意义。)



Answer 4:

我会感到惊讶,如果两者的优化组合是不完全一样的。 如果酒吧是假expensive_foo()将永远不会被调用。



Answer 5:

我看到一个评论,编译器可以重新排序操作,我倾向于这种观点。 以提高串行程序的自动并行化努力造成了一定程度上更好的编译器,它可以帮助程序员避免它们的方案并行的复杂程序。 编译器可能重新排序操作提供了重新排序不违反/恶化的地区或在广义上并不违反的程序的实际意图。

但我怀疑的事实,编译器会尝试重新排列条件语句,如:

  if ( bar && expensive_foo() )

如果更便宜的布尔函数在开始时说,可以肯定的是,我们可以节省一些时间。



文章来源: C++ Conditional operator performance