optimize - java performance tuning



.toArray(neue MyClass[0]) oder.toArray(neue MyClass[myList.size()])? (6)

Angenommen, ich habe eine ArrayList

ArrayList<MyClass> myList;

Und ich möchte nachArray anrufen, gibt es einen Leistungsgrund zu verwenden

MyClass[] arr = myList.toArray(new MyClass[myList.size()]);

Über

MyClass[] arr = myList.toArray(new MyClass[0]);

?

Ich bevorzuge den zweiten Stil, da er weniger ausführlich ist, und ich nahm an, dass der Compiler sicherstellen wird, dass das leere Array nicht wirklich erstellt wird, aber ich habe mich gefragt, ob das stimmt.

Natürlich macht es in 99% der Fälle keinen Unterschied, aber ich möchte einen konsistenten Stil zwischen meinem normalen Code und meinen optimierten inneren Schleifen beibehalten ...


Answer #1

Ab ArrayList in Java 5 wird das Array bereits gefüllt, wenn es die richtige Größe hat (oder größer ist). Folglich

MyClass[] arr = myList.toArray(new MyClass[myList.size()]);

erstellt ein Array-Objekt, füllt es und gibt es an "arr" zurück. Andererseits

MyClass[] arr = myList.toArray(new MyClass[0]);

erstellt zwei Arrays. Der zweite ist ein Array von MyClass mit der Länge 0. Es gibt also eine Objekt-Erstellung für ein Objekt, das sofort weggeworfen wird. Soweit der Quellcode suggeriert, kann der Compiler / JIT diesen nicht so optimieren, dass er nicht erstellt wird. Darüber hinaus führt die Verwendung des Objekts mit der Länge null zu Umsetzungen innerhalb der toArray () - Methode.

Siehe die Quelle von ArrayList.toArray ():

public <T> T[] toArray(T[] a) {
    if (a.length < size)
        // Make a new array of a's runtime type, but my contents:
        return (T[]) Arrays.copyOf(elementData, size, a.getClass());
    System.arraycopy(elementData, 0, a, 0, size);
    if (a.length > size)
        a[size] = null;
    return a;
}

Verwenden Sie die erste Methode, so dass nur ein Objekt erstellt wird und vermeiden Sie (implizite, aber dennoch teure) Castings.


Answer #2

Beispielcode für Ganzzahl:

Integer[] arr = myList.toArray(new integer[0]);

Answer #3

Die Verwendung von 'toArray' mit dem Array der richtigen Größe führt zu besseren Ergebnissen, da die Alternative zuerst das Array mit der Größe null und dann das Array mit der richtigen Größe erstellt. Wie Sie jedoch sagen, ist der Unterschied wahrscheinlich vernachlässigbar.

Beachten Sie auch, dass der Javac-Compiler keine Optimierung durchführt. Heutzutage werden alle Optimierungen zur Laufzeit von den JIT / HotSpot Compilern durchgeführt. Mir sind keine Optimierungen in Bezug auf'Array 'in JVM bekannt.

Die Antwort auf Ihre Frage ist also weitgehend eine Frage des Stils, sollte aber aus Gründen der Einheitlichkeit Bestandteil aller Kodierungsstandards sein, die Sie einhalten (ob dokumentiert oder nicht).


Answer #4

Die zweite ist marginal besser lesbar, aber es gibt so wenig Verbesserung, dass es sich nicht lohnt. Die erste Methode ist schneller, ohne Nachteile zur Laufzeit, also verwende ich sie. Aber ich schreibe es auf die zweite Art, weil es schneller zu tippen ist. Dann kennzeichnet meine IDE es als Warnung und bietet an, es zu beheben. Mit einem einzigen Tastendruck wandelt es den Code vom zweiten Typ in den ersten um.


Answer #5

Moderne JVMs optimieren in diesem Fall die Anordnung der reflektierenden Arrays, so dass der Leistungsunterschied gering ist. Es ist keine gute Idee, die Sammlung zweimal in solch einem Standardcode zu benennen, also würde ich die erste Methode vermeiden. Ein weiterer Vorteil der zweiten ist, dass sie mit synchronisierten und parallelen Sammlungen arbeitet. Wenn Sie eine Optimierung vornehmen möchten, verwenden Sie das leere Array (leere Arrays sind unveränderlich und können gemeinsam genutzt werden) oder verwenden Sie einen Profiler (!).


Answer #6

Verwenden Sie den ersten Fall, weil es einfacher ist und saubereren Code bietet. Der Grund dafür ist, dass die zugrunde liegende Methode, wie die ToArray-Methode funktioniert, eine Kopieroperation ist, die O (n) ist. Die unveränderliche Erinnerung ist keine große Sache. Die Verwaltung solcher Objekte erfolgt sehr effizient und wird auf die gewünschte Größe erweitert.

Optimieren Sie nicht zu viel, bis Sie festgestellt haben, dass ein Engpass in Ihrem Code vorliegt. Wenn Sie zu viel Zeit damit verbringen, dies zu optimieren, verschwenden Sie nur Zeit. Ich bin sicher, es gibt viele andere Dinge, die Sie optimieren können, also würde ich sagen, verwenden Sie einen. Wenn Sie Lesbarkeit und weniger Ausführlichkeit wollen, nehmen Sie die erste. Wenn Sie den zusätzlichen Code nicht mögen und die Klarheit verringern, verwenden Sie Letzteres.





coding-style