C++ 条件运算符性能
C++ Conditional operator performance
我有一个条件语句expensive_foo()
在99.9%的情况下是错误的。我有一个条件语句bar
在~50%的情况下是正确的。
如果这两个陈述都是正确的,我希望采取一些行动。所以我几乎肯定知道expensive_foo()
是假的,只有当bar
是真的时,我才想检查它。
下面的代码会仅在bar
为真时才检查expensive_foo()
吗?还是每次都会检查expensive_foo()
?
if ( bar && expensive_foo() )
{
...
}
或者我需要做一个这样的结构:
if ( bar )
{
if ( expensive_foo() )
{
...
}
}
AND 运算符&&
短路,这意味着当且仅当第一个操作数被计算为 true
时,可以保证第二个操作数被计算。条件if (bar && foo)
和if (bar) if (foo)
是相同的。
鉴于foo
的计算成本很高,您几乎肯定应该先检查bar
。尽管分支预测器不能很好地预测bar
,但与foo
计算相比,这是一个很小的影响。
因此,结构可能应该是:
if (bar)
{
if (bool const foo = compute()) // expensive
{
// ...
}
}
请注意,所有这些结构都意味着我们可能会也可能不会调用compute()
。如果你需要无条件调用函数,那么你应该把它作为第一个检查。在这种情况下,应该利用对结果的成功分支预测。
两个代码只有在bar
为真的情况下才会检查foo
。在第一种情况下,这是由语言惰性布尔表达式计算来保证的(实际上在某些编译器中可以显式关闭,但默认情况下为 ON)。
其他答案很好,但我质疑这个前提。
如果您查询的谓词在 99.9% 的时间内为 false,这类似于在包含 2000 个条目的列表中执行线性搜索,其中您要查找的项目可能位于概率大致相等的任何位置。
在这种情况下,通常会尝试以不同的方式组织列表,以便进行O(logN)(或更好的)搜索而不是O(N)。我不知道你是否能做到这一点,但这就是我要关注的地方。
当一个问题以高度偏斜的概率被问到时,如果可以消除它,这可能是一个很大的加速机会。(假设大部分时间都花在了这项活动上。如果没有,这一点就没有意义了。
如果两者的优化程序集不完全相同,我会感到惊讶。 如果 bar 为 false,则永远不会调用 expensive_foo()。
我看到一条评论说编译器可以重新排序操作,我倾向于这种观点。改进顺序程序自动并行化的努力导致了更好的编译器,它可以帮助程序员避免从他们的程序中使用复杂的并行化例程。编译器可以对操作进行重新排序,前提是重新排序不会违反/恶化局部性,或者在广义上不违反程序的实际意图。
但我怀疑编译器会尝试重新排序条件语句的事实喜欢:
if ( bar && expensive_foo() )
如果将较便宜的布尔函数放在开头,可以肯定的是我们可以节省一些时间。
- 我可以使用条件运算符初始化C风格的字符串文字吗
- C++中的条件运算符 ( ? : ) 可以编译时吗?
- 如何在三元条件运算符中添加换行符和连接? :在 C++ 中
- C++等效于 C# 的 "?." 空条件运算符
- C++具有 void 操作数的条件运算符
- boost::asio::async_read_until 具有自定义匹配条件运算符重载混淆
- C++中的三元条件运算符问题
- 在条件运算符中使用对象两次会产生 UB 吗?
- 条件运算符不允许程序终止
- 在返回语句中嵌套条件运算符
- 为什么这个条件运算符的计算结果为 int?
- 为什么C++不允许在条件运算符中进行隐式列表初始化?
- 是否可以使用条件运算符将输入流传递给函数?
- 使用条件运算符递归计算模板化值或函数时出现错误 C1202(堆栈溢出)
- 具有相同基础类类型的条件运算符
- 条件运算符vs if then else
- 条件运算符的返回类型和两阶段查找
- C++模板元编程:模板类型上的编译时条件运算符
- 使用三元条件运算符时操作数类型不兼容
- C++ 条件运算符性能