对于循环C++可能效率低下

Potentially Inefficient For Loop C++

本文关键字:效率 C++ 于循环 循环      更新时间:2023-10-16

我注意到了以下内容,并认为它效率低下。我错过了什么?我想一定有我不知道的速度优势。对于上下文,这是经纪公司 API 中的生产代码。

我看到了什么:

const unsigned MAX_ATTEMPTS = 50;
unsigned attempt = 0;
for (;;) {
++attempt;
// logic, functions, output
if( attempt >= MAX_ATTEMPTS) {
break;
}
}

我所期望的:

const unsigned MAX_ATTEMPTS = 50;
for(unsigned attempt = 0; attempt < MAX_ATTEMPTS; ++attempt){
// logic, functions, output
}

更正了拼写错误

我注意到以下内容并认为它效率低下。我错过了什么?

除非你知道,否则推测效率是没有意义的

  1. 是否存在可测量的问题
  2. 目前需要多长时间
  3. 需要多长时间
  4. 改进需要多少努力

因此,如果这个循环不是速度关键并且由logic, functions, output主导 - 为避免疑问,除非他们的输出效率比其他任何人都高几个数量级- 那么首先没有问题,你的猜测不太可能是有成效的。

如果这个循环在某种程度上对速度至关重要(我再次强调这不太可能(,那么你需要测量它- 你需要决定什么结果是可以接受的。否则,你只是浪费时间重新安排躺椅,而不是做任何有价值的事情。

最后,如果你通过测试零到两个(包括两个(,你仍然需要判断任何改进是否值得实施、测试、审查和部署它所需的努力。如果结果比步骤 2 中决定的最佳延迟低 1%,并且代码库的其他部分目前正在烧钱,那么这仍然不太可能是重中之重。

然而,从学习而不是商业的角度来看 - 发现这样的潜在低效率是很好的。这不是因为它们很重要,而是因为你可能错了,学习如何对它们进行基准测试的过程 - 以及理解你为什么错了 - 是很好的经验,并将提高你下次的直觉。

唯一的区别是原始代码:

  • 您可以在循环后访问attempt的最后一个值
  • 循环将至少执行一次。

它没有提供明显的好处。如果你问我,原始代码非常丑陋。我会这样做:

unsigned attempt = 1;
do {
// Logic
} while(++attempt <= MAX_ATTEMPTS);

其中一个有可能被编译成更快的代码。为了找出答案,您需要对其进行基准测试。哪一个更快(如果有的话(可能因系统而异。

我认为你削减得太多了,我想是这样的。

for (;;) {
++attempt;
// logic, functions, output
result = somefunc();
if(result == SUCCESS) break;
if( attempt >= MAX_ATTEMPTS) {
break;
}
}

我不喜欢代码中的无数中断。我更喜欢:

do {
// Logic
result = somefunc();
} while(result != SUCCESS && attempt++ < MAX_ATTEMPTS);

如果我是对的,你的版本应该看起来像这样

result = FAILURE;
for(unsigned attempt = 1; result != SUCCESS && attempt <= MAX_ATTEMPTS; ++attempt){
result = somefunc();
// logic, functions, output
}

这些版本之间的性能不会有任何差异。这是个人喜好的问题