在'for-loop'中使用'break'的性能影响
Performance impact of using 'break' inside 'for-loop'
我已经尽了最大的努力,在SO上读了很多问答。是的,但是我还没有找到我的问题的答案。大多数for-loop
和break
相关的问题都涉及嵌套循环,而我关心的是性能。
我想知道在for-loop
中使用break
是否对我的c++代码的性能有影响(假设break几乎从未被调用)。如果有,我也想暂时知道惩罚有多大。
我很怀疑它确实会影响性能(尽管我不知道有多大)。所以我想问你。我的理由如下:
独立于条件语句的额外代码触发
break
(就像if
),它必然是附加的给我的循环的指令。更进一步,当我的编译器试图展开
for-loop
,因为它不再知道迭代的次数它将在编译时运行,有效地将其呈现为while-loop
.因此,我怀疑它确实有性能影响,这是可能的对于非常快速和紧密的循环是相当可观的。
这让我想到了一个后续问题。是for-loop
&break
性能是否等同于while-loop
?就像下面的代码片段一样,我们假设checkCondition()
在99.9%的情况下计算为true
。我是否失去了for-loop
的性能优势?
// USING WHILE
int i = 100;
while( i-- && checkCondition())
{
// do stuff
}
// USING FOR
for(int i=100; i; --i)
{
if(checkCondition()) {
// do stuff
} else {
break;
}
}
我已经在我的电脑上试过了,但是我得到了相同的执行时间。考虑到编译器和它的优化巫术,我想知道概念上的答案。
编辑:
请注意,我在完整的代码中测量了两个版本的执行时间,没有任何真正的差异。此外,我不相信用-s
编译(我通常这样做),因为我对编译器的特定结果不感兴趣。我对这个概念本身(在学术意义上)很感兴趣,因为我不确定我是否完全正确:)
主要的答案是避免在类似的微优化上花费时间,直到您已经验证了这样的条件评估是一个瓶颈。
真正的答案是CPU有强大的分支预测电路,经验证明工作得很好。
将会发生的是,你的CPU将选择是否要采取分支,并执行代码,如果if条件甚至不存在。当然,这依赖于多个假设,比如对条件计算没有副作用(因此,body循环的一部分依赖于它),并且该条件总是被求值为假,直到某一点,它将变为真并停止循环。
一些编译器还允许您指定计算的可能性,作为分支预测器的提示。
如果您想看到两个代码版本之间的语义差异,只需使用-S
编译它们并检查生成的asm代码,没有其他神奇的方法可以做到这一点。
对于"…对性能的影响是什么",唯一合理的答案是"衡量它"。很少有通用的答案。
在您展示的特定情况下,如果优化编译器为这两个示例生成明显不同的代码,那将是相当令人惊讶的。另一方面,我相信像
这样的循环unsigned sum = 0;
unsigned stop = -1;
for (int i = 0; i<32; i++)
{
stop &= checkcondition(); // returns 0 or all-bits-set;
sum += (stop & x[i]);
}
可能比:
快unsigned sum = 0;
for (int i = 0; i<32; i++)
{
if (!checkcondition())
break;
sum += x[i];
}
适用于特定的编译器,特定的平台,设置了正确的优化级别,以及特定的"checkcondition"结果模式。
…但唯一的方法就是测量。
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 在容量内调整矢量大小时的性能影响
- 未达到的情况会影响开关外壳性能
- 数组中的不同浮点值会影响性能 10 倍 - 为什么?
- 为 lambda 分配名称会影响性能吗?
- 通过默认复制构造函数比较 C++ 字符串是否会影响性能,原因为何?
- 每个帧的参考中都有多少性能影响
- C++:if 内部循环的性能影响
- C :对输入验证函数进行编程的性能影响可以对其进行编程,而每次都可以将其编程
- GSL 的预期 (cond) 对运行时施加的性能影响是什么?
- VS2005调试模式和发布模式之间存在巨大的性能影响
- 如何分析指针锯齿的性能影响
- 指针和性能影响
- notify_one性能影响
- 可变长度阵列性能影响 (C/C++)
- 包含每个标头是否有任何性能影响
- 在'for-loop'中使用'break'的性能影响
- 当RVO显示最大的性能影响时
- signal():任何性能影响
- 解引用字符串迭代器和性能影响