Java快捷方式:生成数组以将for循环更改为for-each循环

Java快捷方式:生成数组以将for循环更改为for-each循环,java,performance,foreach,shortcut,Java,Performance,Foreach,Shortcut,我已经考虑过在我的竞赛节目中使用这个快捷方式。我定义了一个函数: private static int[] range(int n) { int[] ret = new int[n]; for (int i = 0; i < n; i++) { ret[i] = i; } return ret; } 而不是: for (int i = 0; i < n; i++) { doit(i); } (inti=0;i

我已经考虑过在我的竞赛节目中使用这个快捷方式。我定义了一个函数:

private static int[] range(int n) {
    int[] ret = new int[n];
    for (int i = 0; i < n; i++) {
        ret[i] = i;
    }
    return ret;
}
而不是:

for (int i = 0; i < n; i++) { doit(i); }
(inti=0;i 此方法是否存在任何重大性能问题?这些问题是什么?

代码有计算解决方案的时间限制,但使用正确的算法通常可以在时间限制的一小部分内完成。range函数在O(n)中运行,因为我们无论如何都要运行一个O(n)循环,所以时间复杂度没有增加。垃圾收集呢?还有什么我没想到的吗

我将确定我是否真的喜欢稍后使用此方法,以及是否值得在比赛开始时键入函数。请不要回答关于款式的问题。(竞争编码产生了一些你所见过的最糟糕的代码,但这一切都是为了按时完成,再也不看了。)



澄清一下,在这场竞争中,实际的编码时间是至关重要的,我们不能带来预输入的代码。这通常意味着也没有代码片段。在匆忙而混乱的编码环境中,
foreach
将加快循环的键入速度,减少出错的可能性。它是C++中宏的替代。 在这种情况下,我更愿意这样做

for (int i = 0; i < n; i++) { doit(i); }
(inti=0;i 在我看来,将其转换为阵列并没有带来任何好处。性能对我来说并不是什么大问题,可能只是第二个问题。首先,我不这样做,因为这是关于写一个更多的方法,这是什么也不给。此外,如果只有1个循环就足够了,为什么还要执行2个循环呢

如果您将编写许多
for循环
,那么
foreach
循环可能并不适用于所有情况,并且您可能最终使用传统的
for循环
,无论如何,可能大多数时间都是这样。你必须考虑我们在编程竞赛中经常遇到的问题。您可能需要循环中的
索引来进行一些计算。谁知道呢。此外,在
foreach
进入Java之前,我发现自己在设计
for循环方面并没有太慢


此外,在竞争中,我们通常不关心性能,除非明确提到性能。如果是这样的话,您的解决方案将不会得到非常积极的对待。

我认为创建阵列不会提高性能

您可能还想看看以下内容:


对于小型阵列,这不会是一个问题(如果不确定,您可以对其进行基准测试)


在哪里做同样的事情更好。Foreach循环可以迭代可重用实例。您可以像您一样创建类RangeIterable实现Iterable,并使静态方法RangeIterable范围(int-from,int-to)。这将是一种更加面向对象的方式,而且在内存方面更便宜。对于[-127128]内的范围,甚至整数装箱也不会成为问题,这是precach整数实例的默认范围

我建议使用:

for(inti=0;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;
  }  
  }
  }

除非
n
足够大,导致空间分配问题。。。我看不出有什么坏处。实际上,出于我自己的目的,我最终实现了类似的功能,但是使用了迭代器而不是数组。至少对于较小的
n
,数组方法应该更快。在编辑器中为
for
添加一个数组上的代码段。一些聪明的IDE甚至会列出阵列供您选择,并为您添加.length。@Koterpillar,不幸的是,我们没有在自己的计算机上进行竞争,因此这可能不是一个选项。同意。我不明白这有什么意义。如果n非常大,那么在竞争环境中会有轻微的性能损失(尽管技术上仍然是O(n),因为我们从2*O(n)中丢弃了2),我将为
循环编写许多
,这种方法可能足够好,可以在竞争过程中节省一些时间/压力。对于直切
foreach
看起来更漂亮。我问的是我可能忽略的任何性能问题,而不是风格建议。@Budgeelnwa:如果你将为循环编写许多
,那么
foreach
look循环可能不适合所有这些,你最终还是使用了传统的
for循环
。你必须考虑我们在编程竞赛中经常遇到的问题。您可能需要循环中的
索引来进行一些计算。谁知道呢。此外,在
foreach
进入Java之前,我发现自己在设计
for loop
时并没有太慢。我不会在任何地方都使用
foreach
,只要它是明确的,“
I
0
n-1
范围内”作为循环。我很清楚两者之间的区别以及如何应用。@Budgeelnwa:如果你很想这样做,那就去吧。绩效可能不是一个标准。如果是这样的话,我会说,完全避免这个把戏。佐尔坦,他从来没有那个意思。当然,这不会提高表现。这个想法是为了提高我的输入/调试性能,而不会使我的解决方案过于缓慢。我喜欢使用自定义Iterable类而不是数组(用于内存)。我将用尽可能少的代码来研究这一点:)希望这对我的情况是可行的。请记住,在这种情况下,您将迭代整数,而不是int,并且,尽管我们从1.5开始就自动装箱/取消装箱,但在使用整数作为int时仍然存在一些问题(一些关于装箱/取消装箱优先级的特殊情况)。当然,你可以
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