Schnellster Weg, um ein Array in Java iterieren: Schleifenvariable vs für Anweisung erweitert [Duplikat]

StackOverflow https://stackoverflow.com/questions/1006395

  •  06-07-2019
  •  | 
  •  

Frage

    

Diese Frage bereits eine Antwort hier:

         

In Java ist es schneller ein Array durchläuft die altmodische Art und Weise,

for (int i = 0; i < a.length; i++)
    f(a[i]);

oder mit der prägnanten Form,

for (Foo foo : a)
    f(foo);

Für eine Arraylist, die Antwort ist das gleiche?

Natürlich für die große Masse des Anwendungscodes, die Antwort ist, es keinen erkennbaren Unterschied macht so die prägnante Form sollte aus Gründen der Lesbarkeit verwendet werden. Doch der Kontext an mich suche, ist schwere technische Berechnung, mit Operationen, die milliardenfach durchgeführt werden müssen, so dass selbst eine kleine Geschwindigkeitsdifferenz könnte seine signifikanten enden.

War es hilfreich?

Lösung

Wenn Sie durch eine Reihe sind Looping, sollte es keine Rolle -. Die for-Schleife verstärkt verwendet Array greift ohnehin

Betrachten wir zum Beispiel diesen Code:

public static void main(String[] args)
{
    for (String x : args)
    {
        System.out.println(x);
    }
}

Wenn Sie mit javap -c Test dekompilierten wir bekommen (für die main-Methode):

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

Jetzt ist es ändern, um einen expliziten Array-Zugriff zu verwenden:

public static void main(String[] args)
{
    for (int i = 0; i < args.length; i++)
    {
        System.out.println(args[i]);
    }
}

Diese dekompiliert zu:

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

Es ist ein bisschen mehr Setup-Code in der for-Schleife verbessert, aber sie sind im Grunde das gleiche tun. Keine Iteratoren beteiligt sind. Darüber hinaus würde ich erwarten, dass sie JITted zu noch ähnlichem Code zu erhalten.

Vorschlag: wenn Sie wirklich denken, es könnte einen signifikanten Unterschied machen (die es nur würde immer tun, wenn der Körper der Schleife absolut miniscule ist), dann sollten Sie Benchmark es mit Ihrer realen Anwendung. Das ist die einzige Situation, die wichtig ist.

Andere Tipps

Dies fällt direkt in der Arena von Mikro-Optimierung . Es spielt wirklich keine Rolle. Stilistisch ziehe ich immer die zweite, weil es prägnanter ist, es sei denn, Sie den Schleifenzähler für etwas anderes brauchen. Und das ist viel wichtiger als diese Art von Mikro-Optimierung . Lesbarkeit

Dass gesagt wird, für eine Arraylist gibt es nicht viel Unterschied, aber ein LinkedList wird mit dem zweiten wesentlich effizienter sein.

es messen. Die Antwort auf all leistungs Fragen kann auf VM-Version abhängig, Prozessor, Speicher-Geschwindigkeit, Cache-Speicher etc. So können Sie es für die jeweilige Plattform messen müssen.

Persönlich würde ich die zweite Variante bevorzugen, weil die Absicht mehr klar. Wenn die Leistung ein Problem wird, kann ich es optimieren später sowieso -. Wenn dieser Code wirklich wichtig für die Leistung der gesamten Anwendung ist

Für eine LinkedList:

for(ClassOfElement element : listOfElements) {
  System.out.println(element.getValue());
}

Es wurde beantwortet vor:

Ist zwischen einem ein Leistungsunterschied für Schleife und eine for-each-Schleife?

Auf einem Array oder Random Sammlung Sie eine kleine Erhöhung der Geschwindigkeit erhalten können, indem Sie:

List<Object> list = new ArrayList<Object>();

for (int i=0, d=list.size(); i<d; i++) {
    something(list.get(i));
}

Aber ich würde nicht im Allgemeinen kümmern. Optimierungen wie diese Gewohnheit machen mehr als 0,1% Unterschied zu Ihrem Code. Versuchen Sie Java-Aufruf mit -Prof , um zu sehen, wo der Code seine Zeit tatsächlich zu verbringen.

Noch schneller ist die ParallelArray des Gabel-Join-Framework zu verwenden (wenn Sie groß genug, um Daten-Set haben).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top