Ist ArrayList.size () - Methode zwischengespeichert?
Frage ich mich, ist das size()
Methode, die Sie aufrufen können auf eine bestehende ArrayList<T>
zwischengespeichert?
Oder ist es besser in performance-kritischen code, dass ich einfach speichern size()
in einem lokalen int?
Ich würde erwarten, dass es in der Tat zwischengespeichert, wenn Sie nicht das hinzufügen/entfernen von Elementen zwischen den anrufen zu size()
.
Habe ich Recht?
update
Ich spreche nicht von inlining oder solche Dinge. Ich will nur wissen ob die Methode size()
selbst speichert den Wert intern, oder dass es dynamisch berechnet jedes mal, wenn Sie aufgerufen.
- Es ist ein schnelles rufen Sie für ArrayList, aber speichern Sie das Ergebnis in die lokale variable, wenn Sie es verwenden, wie ein test der Bedingung in jeder loop-iteration.
- können Sie bitte klären Sie die Frage. Es scheint, dass einige Leute interpretieren dies als "does size() führen Sie eine Berechnung oder ist es trivial return ein Feld" vs. "werden mehrere Aufrufe size() ersetzt werden, mit einem einzigen Aufruf von size() mit den nachfolgenden Anrufungen ersetzt durch eine lokale variable, in die das Vorherige Ergebnis wurde gespeichert". Ich habe interpretiert, als die letzteren, während andere interpretiert haben als die ersteren. Bitte stellen Sie das klar.
- Vielen Dank für die Klarstellung.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich glaube nicht, ich würde sagen, es ist "im Cache" als solches - aber es ist einfach gespeichert in einem Feld, so ist es schnell genug, um anzurufen Häufig.
Sun JDK Implementierung von
size()
ist nur:Java HotSpot(TM) Client VM (build 1.5.0_22-147, mixed mode, sharing)
und über 1/2 der Zeit mitJava HotSpot(TM) 64-Bit Server VM (build 14.3-b01-101, mixed mode)
. Gibt es etwas, was ich bin fehlt?size()
Methode.Ja.
Einen kurzen Blick auf den Java-Quellcode würde dir die Antwort sagen.
src.zip
- Datei in Ihrem JDK-Installationsverzeichnis.java.util.ArrayList
? Es gibt eineprivate int size;
auf Linie 98 (in Sun JDK 1.6.0_20).Dies ist die Umsetzung in OpenJDK version:
So, es ist so gut wie ein Methodenaufruf zu erhalten. Es ist nicht sehr wahrscheinlich, dass die HotSpot-caches den Wert dieser Methode zurückgegeben wird, also, wenn Sie wirklich , DASS besorgt sind, können Sie cache-it-yourself. Es sei denn, Ihr profiling hat gezeigt, dass dies ein Flaschenhals, obwohl (nicht sehr wahrscheinlich), sollte man einfach beschäftigen Sie sich mit der Lesbarkeit eher, als ob ein einfacher Aufruf der Methode liefert den Wert eines Feldes zwischengespeichert wird oder nicht.
Weiß ich nicht sicher beantworten, aber meine Vermutung wäre: Nein. Es gibt keine Möglichkeit für einen Java-compiler, kurz von besonderen Gehäuse ArrayList, zu wissen, dass die Funktionen, die Sie aufrufen, werden nicht mutiert und dass, als Ergebnis, der Aufruf von size() sollte den gleichen Wert zurückgeben. Deshalb finde ich es sehr unwahrscheinlich, dass ein Java-compiler Faktor wiederholte Aufrufe size() und speichern Sie Sie in einem temporären Wert. Wenn Sie das Niveau der Optimierung, dann sollten Sie speichern den Wert in eine lokale variable selbst. Ansonsten, ja, Sie bezahlen für den Funktion-Aufruf-overhead im Zusammenhang mit dem Aufruf der size () - Methode. Beachten Sie jedoch, dass die size () - Methode ist O(1) für ArrayList (obwohl der Funktionsaufruf-overhead ziemlich heftige). Persönlich würde ich den Faktor, der aus einem Aufruf von size() aus Schleifen und manuell speichern Sie diese in einem lokalen (wo zutreffend).
Bearbeiten
Auch wenn so eine Optimierung nicht durchgeführt werden kann durch einen Java-compiler, es wurde treffend darauf hingewiesen, dass der JIT-können inline die Umsetzung der ArrayList.size (), so dass es nur Kosten das gleiche wie ein Feld zuzugreifen, ohne zusätzlichen Aufruf der Methode Aufwand, so dass im Effekt die Kosten sind vernachlässigbar, obwohl Sie vielleicht noch sparen leicht durch manuelles speichern in einer temporären (die möglicherweise beseitigen memory-lookup-stattdessen dienen die variable aus einem CPU-register).
size()
hat in der Tat zurück, ohne durchführen von zusätzlichen Berechnungen verwenden, und den code nicht wissen, welche Methode Implementierungen anpassen von Größe und welche nicht. Ihre Diskussion von Compilern ist ein Roter Hering, umgesetzt wird dies auf Quellcode-Ebene und ist sehr einfach. Außerdem sagen Sie, dass Sie die Antwort nicht wissen, für sicher, dass (wenn es dauern würde, zwei Minuten zu überprüfen) und die Beantwortung ohnehin nicht sehr hilfreich.Die offensichtliche Umsetzung der ArrayList wäre zum speichern der Größe intern in einem Feld. Ich wäre sehr überrascht, wenn es jemals zu werden berechnet, auch nach der Größenänderung.
Warum würde es sein? ArrayList implementiert das List-interface, unterstützt durch ein array, nachdem alle.
Ich würde annehmen, dass es nur noch eine
size
Mitglied, dass ist erhöht, wenn Sie legen Sie Dinge, und verringert, wenn Sie zu entfernen, und dann ist es nur die Renditen, die.Habe ich noch nicht angeschaut, mehr als die API-docs, jetzt, wenn.
Wenn das Zwischenspeichern das Ergebnis der
size()
Methode würde die Leistung spürbar verbessern (was es oft tut - ich regelmäßig zu sehenArrayList.size()
als top-kompilierten Methode in meinem-Xprof
Ausgang), dann betrachten Umwandlung die ganze Liste in ein array für eine noch größere Beschleunigung.Hier ist ein trick, der funktionieren kann, wenn Sie die Liste Durchlaufen, regelmäßig aber nur selten aktualisieren: