maneira mais rápida para iterar uma matriz em Java: variável do laço vs instrução for aprimorada [duplicado]
-
06-07-2019 - |
Pergunta
Esta questão já tem uma resposta aqui:
Em Java, é mais rápido para percorrer um array a maneira old-fashioned,
for (int i = 0; i < a.length; i++)
f(a[i]);
Ou através do formulário mais conciso,
for (Foo foo : a)
f(foo);
Para uma ArrayList, é a resposta da mesma?
É claro que para a grande maioria do código do aplicativo, a resposta é não faz diferença perceptível assim que mais forma concisa deve ser usado para facilitar a leitura. No entanto, o contexto que eu estou olhando é pesados ??computação técnica, com operações que devem ser executadas bilhões de vezes, por isso mesmo uma pequena diferença de velocidade pode acabar sendo significativo.
Solução
Se você está em loop através de uma matriz, não deve importar -. A aprimorado para variedade usos de loop acessa de qualquer maneira
Por exemplo, considere o seguinte código:
public static void main(String[] args)
{
for (String x : args)
{
System.out.println(x);
}
}
Quando compilado com javap -c Test
temos (para o método main
):
public static void main(java.lang.String[]);
Code:
0: aload_0
1: astore_1
2: aload_1
3: arraylength
4: istore_2
5: iconst_0
6: istore_3
7: iload_3
8: iload_2
9: if_icmpge 31
12: aload_1
13: iload_3
14: aaload
15: astore 4
17: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
20: aload 4
22: invokevirtual #3; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
25: iinc 3, 1
28: goto 7
31: return
Agora, alterá-lo para utilizar um acesso de matriz explícita:
public static void main(String[] args)
{
for (int i = 0; i < args.length; i++)
{
System.out.println(args[i]);
}
}
Este Decompila para:
public static void main(java.lang.String[]);
Code:
0: iconst_0
1: istore_1
2: iload_1
3: aload_0
4: arraylength
5: if_icmpge 23
8: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
11: aload_0
12: iload_1
13: aaload
14: invokevirtual #3; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
17: iinc 1, 1
20: goto 2
23: return
Há um código de configuração pouco mais no loop for aprimorado, mas eles estão fazendo basicamente a mesma coisa. Não iterators estão envolvidos. Além disso, eu esperaria-los para obter JITted ao código ainda mais similar.
Sugestão: se você realmente acha que pode fazer uma diferença significativa (que seria apenas nunca fazer se o corpo do laço é absolutamente minúsculo), então você deve referência-lo com sua aplicação real. Essa é a única situação que importa.
Outras dicas
Esta recai na arena da micro-otimização . Ele realmente não importa. Estilisticamente Eu sempre prefiro a segunda porque é mais concisa, a menos que você precisa do contador de loop para outra coisa. E isso é muito mais importantes do que esse tipo de micro-otimização :. Legibilidade
Dito isto, para um ArrayList não haverá muita diferença, mas um LinkedList vai ser muito mais eficiente com o segundo.
medi-la. A resposta em todos os desempenho-pergunta pode depender de VM-versão, processador, memória de velocidade, caches etc Então, você tem que medir-lo para sua plataforma específica.
Pessoalmente eu prefiro a segunda variante, porque a intenção é mais clara. Se o desempenho se torna um problema que pode otimizá-lo mais tarde, de qualquer maneira -. Se esse código é realmente importante para o desempenho de toda a aplicação
Para uma LinkedList:
for(ClassOfElement element : listOfElements) {
System.out.println(element.getValue());
}
Foi respondida antes:
é existe uma diferença de desempenho entre um loop e uma for-each loop?
Em um array, ou uma coleção RandomAccess você pode obter um pequeno aumento na velocidade fazendo:
List<Object> list = new ArrayList<Object>();
for (int i=0, d=list.size(); i<d; i++) {
something(list.get(i));
}
Mas eu não me preocuparia em geral. Otimizações como este não vai fazer diferença mais do que 0,1% de seu código. Tente invocar java com -prof para ver onde o código está realmente gastando seu tempo.
Ainda mais rápido é usar o ParallelArray do quadro fork-join (se você tem conjunto de dados grande o suficiente).