我考虑过在比赛编程中使用这个快捷方式。我定义了一个函数:
private static int[] range(int n) {
int[] ret = new int[n];
for (int i = 0; i < n; i++) {
ret[i] = i;
}
return ret;
}
这样我就可以稍微更快地编写我的for循环,并且稍微整洁一点(扫描代码时):
for (int i: range(n)) { doit(i); }
而不是:
for (int i = 0; i < n; i++) { doit(i); }
此方法是否存在重大性能问题?它们是什么?
代码有一个计算解决方案的时间限制,但使用正确的算法通常可以在一小部分时间内完成此操作。范围函数在O(n)中运行,因为无论如何我们将运行O(n)循环,时间复杂度没有增加。垃圾收集怎么样?还有其他我没想到的东西吗?
我将在稍后确定我是否真的喜欢使用此方法,并且如果在比赛开始时输入功能是值得的。 请不要回答关于风格的问题。(竞争编码会产生一些你见过的最糟糕的代码,但这都是关于按时完成它并且再也不会再看它了。)< / p>
为了澄清,实际编码时间在本次比赛中至关重要,我们无法提供预先输入的代码。这通常意味着没有代码片段。在匆忙和凌乱的编码环境中,foreach
将使循环更快,更容易出错。它是C ++中宏的替代品。
答案 0 :(得分:2)
在这种情况下,我更愿意这样做。
for (int i = 0; i < n; i++) { doit(i); }
将其转换为数组实际上没有任何好处,IMO。在这里,性能对我来说并不是一个问题,可能会是第二个。首先,我不这样做,因为它是关于再写一个方法,它没有给出任何东西。而且,为什么只用1就可以执行2个循环。
如果你写了很多for-loops
,那么foreach
循环可能不适合所有情况,你可能最终会使用传统的for-loop
,无论如何,也许大部分时间。你必须考虑我们在编程竞赛中经常遇到的问题。您可能需要循环中的index
来进行一些计算。谁知道。此外,在for-loop
进入Java之前,我没有发现自己在提出foreach
方面的速度太慢。
此外,在比赛中我们通常不关心表现,除非明确提到。如果是的话,你的解决方法就不会非常积极。
答案 1 :(得分:2)
我建议使用:
for (int i = 0; i < n; i++) { doit(i); }
如果您正在寻找快速执行时间。
在为i分配值时,其他方法将花费时间执行数组查找和复制值。
我尝试运行快速测试来验证:
class Main {
private static int[] range(int n) {
int[] ret = new int[n];
for (int i = 0; i < n; i++) {
ret[i] = i;
}
return ret;
}
public static void main (String[] args) throws java.lang.Exception
{
int n = 10;
for(int x =0; x<3; x++){
int[] ret = range(n);
long t1 = System.nanoTime() ;
for (int i: ret ) { }
long t2 = System.nanoTime() ;
for (int i = 0; i < n; i++) { }
long t3 = System.nanoTime() ;
System.out.println(n + " : " + (t2-t1));
System.out.println(n + " : " + (t3-t2));
n = n*n;
}
}
}
获得的结果是:
10 : 1382
10 : 728
100 : 5239
100 : 1774
10000 : 450105
10000 : 1741059
答案 2 :(得分:1)
对于小阵列,它不会是一个问题(如果你不确定,你可能只是对它进行基准测试。)
哪里有更好的方法来做同样的事情。 Foreach循环可以迭代Iterable实例。您可以创建类RangeIterable实现Iterable,并使静态方法RangeIterable范围(int from,int to),就像您一样。这将是一个更多的OOP方式,它在内存方面更加清晰。甚至整数装箱也不会成为[-127,128]内的范围的问题,这是预处理整数实例的默认范围
答案 3 :(得分:0)