【问题标题】:Potentially Inefficient For Loop C++对于循环 C++ 可能效率低下
【发布时间】:2020-06-27 23:09:44
【问题描述】:

我注意到以下内容并认为它效率低下。我错过了什么?我想一定有我不知道的速度优势。就上下文而言,这是经纪公司 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
}

*** 纠正错字

【问题讨论】:

  • 它们有不同的功能(假设(2)中的错字):(1)将无条件地执行一次逻辑功能。 (2) 如果进入时退出条件为真,则不会。
  • for(unsigned attempt = 1; attempt &lt;= MAX_ATTEMPTS; ++attempt) 大概。
  • 在他们的代码中,循环体看到attempt,范围从1到MAX_ATTEMPTS。在你的,它看到 0 到 MAX_ATTEMPTS - 1
  • 这类问题的答案总是一样的:简介、简介、简介。
  • @tadman 好吧,我很傻。没看标题。

标签: c++ loops for-loop


【解决方案1】:

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

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

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

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

如果这个循环在某种程度上对速度至关重要(我再次强调这是多么不可能),那么您需要对其进行测量 - 并且您需要确定结果是什么可以接受。否则你只是在浪费时间重新布置躺椅,而不是做任何有价值的事情。

最后,如果您通过两次测试通过零测试,您仍然需要判断任何改进是否值得实施、测试、审查和部署所需的努力。如果事实证明它比第 2 步确定的最佳延迟低 1%,并且您的代码库的其他部分目前正在烧钱,那么这仍然不太可能是首要任务。

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

【讨论】:

    【解决方案2】:

    唯一的区别是在原始代码中:

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

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

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

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

    【讨论】:

    • 关于速度或效率,请记住代码通常由编译器优化(您可以使用必要的标志来控制优化)
    • @user4581301 这就是为什么我初始化为 1 而不是 0
    • 哎呀。错过了。,
    • ++attempt &lt; MAX_ATTEMPTS 解决了你提到的最后一个问题。
    • @KorelK 已修复
    【解决方案3】:

    我觉得你剪得太多了,我猜是这样的。

    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
    }
    

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

    【讨论】:

      猜你喜欢
      • 2020-10-10
      • 1970-01-01
      • 2011-03-08
      • 2019-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-16
      • 1970-01-01
      相关资源
      最近更新 更多