在for循环内使用条件语句还是使用多个for循环?

3

我想让我的代码在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);

希望能够解释一下哪个更好的原因,这对于IT技术相关内容非常有帮助。提前感谢您的回复:>

1
运行每个版本一百万次,并计时。 - Some programmer dude
2
实际上,不要在第一(或第二、第三等)时间考虑性能或“增强速度”。相反,专注于编写良好、可读和易于维护的代码,并确保其正常工作。然后,如果它还不够好(通常足够好),或者您有特定的性能要求,那么您可以测量、基准测试和分析代码,找出最糟糕的瓶颈并修复它们(同时提供文档、注释和单元测试)。 - Some programmer dude
5个回答

3

提高速度不应该是考虑因素。差异(如果有)将是微不足道的。

你应该选择更易读的版本。当使用 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);
}

我猜差别可能只有千分之一毫秒左右,仅出于好奇。无论如何,还是要考虑可读性。谢谢! - Juneyong Park
通过比较,@eran可以看出单个循环会有更多的比较。因此,它间接影响了性能。 - Hasnain Ali Bohra
@HasnainAliBohra 如果讨论一个有30次迭代的循环的性能没有意义。即使我们在谈论数百万次迭代,我也怀疑时间差异是否有意义。 - Eran
虽然我同意你应该使用多个循环,但我不同意你的理由。你应该使用多个循环,因为这样可以完全避免分支,从而对性能产生不利影响(尽管在这种情况下影响微乎其微)。归根结底,对于这样的操作,真的没有什么区别。至于可读性,两种方法都是绝对没问题的,任何一个有经验的开发人员都不会对你提出质疑。 - apexlol

2
第一个单循环分析: 初始化的变量数为1。 比较次数为:
  1. 1 < 31

  2. 1 < 11

  3. 2 < 31

  4. 2 < 11 以此类推。

因此,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梯级好。


1

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

模式1:

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

模式2:

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

0

除非出于性能考虑,否则应以可读性为先。第二个代码块肯定更容易理解。尽管我建议使用块语句:

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循环或者一些在编译时无法确定的循环,那么这可能是最好的方法。


0

这3个for循环比较快(在这里不是很重要),因为每个i步骤上不再有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级联是一种改进。这些表达式在阅读时更难解释,但它们指定了一些计算逻辑,而仅仅陈述if条件则不会: 你可以将30更改为300,仍然一切都有意义。 或者
for (int j = 0; j < 3; ++j) {
    for (int i = 1 + j*10; i < 11 + j*10; i++) {
        System.out.println((3-j)*i);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接