我已经尽了最大努力,阅读了很多Q& As SO.SE,但我还没有找到我特定问题的答案。大多数for-loop
和break
相关问题都是指嵌套循环,而我则关注性能。
我想知道在break
中使用for-loop
是否会对我的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
编译(我通常这样做),因为我对编译器的特定结果不感兴趣。我对这个概念本身很感兴趣(在学术意义上)因为我不确定我是否完全正确:)
答案 0 :(得分:7)
主要答案是在确认此类条件评估是瓶颈之前,避免花时间进行类似的微观优化。
真正的答案是CPU具有强大的分支预测电路,这些电路在经验上非常有效。
将会发生的情况是,您的CPU将选择是否接受分支,并执行代码,就像if条件不存在一样。当然,这依赖于多种假设,例如对条件计算没有副作用(因此身体循环的一部分取决于它),并且该条件将始终评估为假,直到它将变为真的某一点。停止循环。
某些编译器还允许您指定评估的可能性,作为提示分支预测器。
如果你想看到两个代码版本之间的语义差异,只需用-S
编译它们并检查生成的asm代码,就没有其他神奇的方法可以做到。
答案 1 :(得分:3)
"唯一合理的答案是什么?"的性能影响是"测量它"。答案非常少。
在您展示的特定情况下,如果优化编译器为这两个示例生成显着不同的代码,那将是相当令人惊讶的。另一方面,我可以相信一个循环:
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];
}
针对特定平台,针对特定平台,设置了正确的优化级别,以及特定模式的&#34; checkcondition&#34;结果
......但唯一的方法就是衡量。