简体   繁体   English

C ++条件运算符性能

[英]C++ Conditional operator performance

I've a conditional statement expensive_foo() which is false in 99.9% cases. 我有一个条件语句expensive_foo()在99.9%的情况下为false。 And I have a conditional statement bar which is true in ~50% cases. 我有一个条件语句bar ,在大约50%的情况下是正确的。

And I want some action be done if both statements are true. 如果两个陈述都正确,我想采取一些行动。 So I almost certainly know that expensive_foo() is false and I want to check it only if bar is true. 因此,我几乎可以肯定知道expensive_foo()为假,并且我只想在bar为true时检查它。

Will the code below check the expensive_foo() ONLY if bar is true? 如果bar为true,则下面的代码仅会检查一下expensive_foo()吗? Or it will check expensive_foo() every time? 还是会每次都检查expensive_foo()

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

Or I need to make a structure like this: 或者我需要制作一个像这样的结构:

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

The logical AND operator && is short-circuited, which means that it is guaranteed the second operand is evaluated if and only if the first one is evaluated as true . 逻辑AND运算符&&短路,这意味着可以保证仅当第一个操作数被评估为true ,第二个操作数才被评估。 The conditions if (bar && foo) and if (bar) if (foo) are identical. if (bar && foo)if (bar) if (foo)条件相同。

Given that foo is expensive to compute, you should almost definitely check bar first. 鉴于foo计算成本很高,因此您几乎应该绝对先检查一下bar Even though bar won't be predictable by the branch predictor very well, that's a minor effect compared to the computation of foo . 即使bar不能被分支预测器很好地预测,与foo的计算相比,这是一个很小的影响。

Thus the structure should probably be: 因此,结构可能应该是:

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

Note that all of those constructions mean that we may or may not call compute() . 请注意,所有这些构造都意味着我们可能会或可能不会调用compute() If you require the function call unconditionally, then you should make it the first check. 如果您需要无条件调用该函数,则应首先对其进行检查。 In that case, the successful branch prediction on the result should be exploited. 在这种情况下,应该利用对结果的成功分支预测。

Both codes will check foo only in case bar is true. 这两个代码仅在bar为true时才检查foo In first case this is guaranteed by the language lazy boolean expression evaluation (which actually could be explicitly turned off in some compilers, but is ON by default). 在第一种情况下,这是通过语言惰性布尔表达式评估来保证的(实际上可以在某些编译器中将其显式关闭,但默认情况下为ON)。

The other answers are good, but I'm questioning the premise. 其他答案很好,但是我在质疑前提。

If you are querying a predicate that is false 99.9% of the time, that is analogous to doing linear search in a list of 2000 entries, where the item you are looking for could be anywhere with roughly equal probability. 如果您要查询99.9%的时间是错误的谓词,则类似于在2000个条目的列表中进行线性搜索,在此条件下,您要查找的项目可能位于概率大致相等的任何地方。

In that case, typically one would try to organize the list differently so as to do a O(logN) (or better) search instead of O(N). 在这种情况下,通常会尝试以不同的方式组织列表,以便进行O(logN)(或更优)搜索而不是O(N)。 I don't know if you can do this, but that is where I would focus. 我不知道您是否可以这样做,但这就是我要重点关注的地方。

When a question is being asked with highly skewed probability, that can be a big speedup opportunity, if one can un-skew it. 当一个问题以高度偏斜的概率被问到时,如果可以使它偏斜,那将是一个很大的加速机会。 (Assuming a big % of time is spent in this activity. If not, the point is moot.) (假设在此活动中花费了很大的时间。如果没有,那很重要。)

I'd be surprised if the optimized assembly for both wasn't exactly the same. 如果两者的优化组件不完全相同,我会感到惊讶。 expensive_foo() will never be called if bar is false. 如果bar为false,则永远不会调用luxury_foo()。

I saw a comment that the compiler can re-order operations and I'm inclined to that opinion. 我看到一条评论,认为编译器可以重新排序操作,我倾向于这种观点。 The efforts to improve automatic parallelization of the sequential programs has resulted in somewhat better compilers and it helps a programmer to avoid complex routines of parallelization from their programs. 改善顺序程序的自动并行化的努力导致了更好的编译器,它有助于程序员避免程序中复杂的并行化例程。 The compiler could re-order the operations provided the re-ordering does not violate/worsen the locality or in a broad sense doesn't violate the actual intention of the of the program. 编译器可以对操作进行重新排序,前提是重新排序不违反/不喜欢本地性,或者在广义上不违反程序的实际意图。

But I doubt the fact that the compiler would try to re-order a conditional statement like : 但是我怀疑编译器会尝试重新排序条件语句,例如:

  if ( bar && expensive_foo() )

If the less expensive Boolean function is put at the beginning, it is certain that we can save some time. 如果将较便宜的布尔函数放在开头,则可以肯定我们可以节省一些时间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM