【问题标题】:Conditional inside for loop or lots of for loop?有条件的 for 循环还是很多 for 循环?
【发布时间】:2018-06-26 06:42:57
【问题描述】:

我试图让我的代码在 for 循环中针对 i 的不同值以不同的方式工作,但我不知道我是否应该让条件进入循环内部,或者只是创建多个 for 循环以提高速度。

我的英语在解释事情上似乎效率很低,所以这里有一个例子:

for (int i = 1; i < 31; i++) {
    if (i < 11) {
        System.out.println(3*i);
    } else if (i<21) {
        System.out.println(2*i);
    } else System.out.println(i);
}

for (int i = 1; i < 11; i++) System.out.println(3*i);
for (int i = 11; i < 21; i++) System.out.println(2*i);
for (int i = 21; i < 31; i++) System.out.println(i);

如果其中一个可能更好或不更好的原因也能得到解释,那将非常有帮助。提前谢谢你:>

【问题讨论】:

  • 每个版本运行一百万次,然后计时。
  • 真的,不要关心你做的第一件事(或第二、第三等)的性能或“提高速度”。而是专注于编写好的、可读的和可维护的代码,并且它可以工作。然后,如果它不够好(并且足够好通常足够好)或者您有某些性能要求,那么您可以测量、基准测试和分析代码以找到最严重的瓶颈并修复它们(使用文档, cmets 和单元测试)。

标签: java for-loop conditional


【解决方案1】:

不应考虑提高速度。差异(如果有的话)可以忽略不计。

您应该选择更易读的版本。当使用for 循环时,通常意味着您希望执行相同的操作N 次。在您的情况下,您想要执行 3 个不同的操作,每个操作不同的次数(或对于 i 的不同值)。因此,有 3 个循环更有意义。

for (int i = 1; i < 11; i++) {
    System.out.println(3*i);
}
for (int i = 11; i < 21; i++) {
    System.out.println(2*i);
}
for (int i = 21; i < 31; i++) {
    System.out.println(i);
}

【讨论】:

  • 我猜差异可能是千分之一毫秒或类似的东西。只是出于好奇。无论如何谢谢你!会记住可读性。
  • @eran 通过查看比较。单循环会比较多,所以间接影响性能
  • @HasnainAliBohra If 讨论具有 30 次迭代的循环的性能没有意义。即使我们谈论的是数百万次迭代,我也怀疑时差是否有意义。
  • 虽然我同意你应该使用多个循环,但我不同意这个推理。您应该使用多个循环,因为您完全否定了分支,这会对性能产生不利影响(尽管在这种情况下是最小的)。底线是,对于这样的操作,这真的无关紧要。至于可读性,两者都很好,没有任何值得他们盐分的开发人员会质疑你的解决方案。
【解决方案2】:

第一个单循环分析:- 初始化的变量数 1。 比较次数:-

  1. 1

  2. 1

  3. 2

  4. 2

因此对于 1 到 10 的比较数为 20。

对于 11 到 20 的数量比较 30。 对于 21 到 30 的比较数为 30。

所以总共 80 个比较单循环。 但是

for (int i = 1; i < 11; i++) System.out.println(3*i);
for (int i = 11; i < 21; i++) System.out.println(2*i);
for (int i = 21; i < 31; i++) System.out.println(i);

总比较 31.

所以单独的循环是好的,而不是 if else ledder。

【讨论】:

    【解决方案3】:

    让代码可读更重要。性能差异很小,在大多数情况下可以忽略不计。这是我电脑上的实验结果:

    模式 1:

    • 运行 100000 次花费 7548 毫秒
    • 运行 1000000 次花费 70180 毫秒

    模式 2:

    • 运行 100000 次花费 7536 毫秒
    • 运行 1000000 次花费 70535 毫秒

    【讨论】:

      【解决方案4】:

      除非出于性能考虑,否则请让可读性引导您。 第二个肯定更容易理解。虽然我建议使用块语句:

      for (int i = 1; i < 11; i++) {
          System.out.println(3*i);
      }
      for (int i = 11; i < 21; i++) {
          System.out.println(2*i);
      }
      for (int i = 21; i < 31; i++) {
          System.out.println(i);
      }
      

      当然你可以做一个公式:

      for (int i = 1; i < 31; i++) {
          int fac=3-((i-1)/10);
          System.out.println(fac*i);
      }
      

      虽然这看起来也相当不可读,但如果等效的有许多 for-loops 或许多您在编译时无法确定的循环,它可能是最好的方法。

      【讨论】:

        【解决方案5】:

        3 个 for 循环更快(这里不重要),因为在每个 i-step 不再有 if-else-if。更重要的是,这三个循环更具可读性,因为删除了 if 级联。

        但是使用j = i + 1 可以将第一个循环转换为:

        final int n = 30;
        for (int j = 0; j < n; j++) {
            int k = n/10 - j/10;
            System.out.println(k * (j + 1));
        }
        

        由于除法,这可能不会更快。然而,删除 if-cascade 是一种改进。这些表达式在阅读时更难解释,但它们指定了一些计算逻辑,仅说明 if 条件不会:一个可以将 30 更改为 300,但仍然一切都有意义。 p>

        或者

        for (int j = 0; j < 3; ++j) {
            for (int i = 1 + j*10; i < 11 + j*10; i++) {
                System.out.println((3-j)*i);
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2013-08-07
          • 2016-04-10
          • 2014-05-17
          • 2023-01-29
          • 2011-09-02
          • 1970-01-01
          • 2012-10-20
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多