ist es besser ein lokales Objekt zu erstellen.

Status
Nicht offen für weitere Antworten.

Chris_1980

Bekanntes Mitglied
Hy,

hab da mal ne allgemeine frage, wenn ich eine Liste oder n Array durchgehe, und zwei oder mehr mal ne Methode aufrufe, wie in dem oberen Codefragment die getMethode der ArrayList, ist es dann Performance-technisch besser
ein lokales Objekt zu erstellen (wie im unteren Codefragment) und das dann zu benutzen oder bleibt das gleich? ???:L

Code:
			for(int i=0 ; i<blockList.size() ; i++)
			{
				
				if(blockList.get(i).getLifes() <= 0 
						&& !blockList.get(i).isPaintingHitAnimation())  blockList.remove(i);
			}


Code:
			Block b;
			for(int i=0 ; i<blockList.size() ; i++)
			{
				b = blockList.get(i);
				if(b.getLifes() <= 0 
						&& !b.isPaintingHitAnimation())  blockList.remove(i);
			}
 
B

Beni

Gast
Stell dir mal vor, "get" würde eine Sekunde zur Ausführung benötigen. Im oberen Fall wären das dann "blockList.size()*3" Sekunden, im unteren Fall nur "blockList.size()" Sekunden :arrow: mit einer lokalen Referenz kann man durchaus ein bisschen was gewinnen. Im Falle einer ArrayList ist das nicht sehr viel, bei einer LinkedList könnte es bereits bemerkbar sein.

P.S. und das "blockList.size()" könnte man auch durch eine Variable ersetzen, das Ding wird viel zu oft ausgeführt :wink:
 

Lim_Dul

Top Contributor
Wobei size() meines Wissens bei den meisten (allen?) Listen in O(1) geht, daher ist das nicht so dramatisch.
 

Chris_1980

Bekanntes Mitglied
ok, danke für die Info. :)
(War mir einfach nicht sicher ob das nach dem Compilieren noch ne Bedeutung hat.)

MFG
 

Marco13

Top Contributor
Man kann davon ausgehen, dass der Compiler das wegoptimiert (Im Zweifelsfall mal ein Testprogramm mit "ein paar Millionen" Schleifendurchläufen machen, und die Ausführungszeit messen, oder es im Profiler laufen lassen.).

Ich würde die dritte Variante verwenden
Code:
         for(int i=0 ; i<blockList.size() ; i++)
         {
            Block b = blockList.get(i);
            if(b.getLifes() <= 0
                  && !b.isPaintingHitAnimation())  blockList.remove(i);
         }
(d.h. die Deklaration IN der Schliefe), oder, wenn es sein muss, die zweite Variante von dir. Ganz allein schon deswegen, weil es viel übersichtlicher ist. Spätestens wenn man dann solche Konstrukte hat wie
Code:
     for(int i=0 ; i<blockList.size() ; i++) {
       for(int j=0 ; i<blockList.get(i).entries(); j++) {
         for(int k=0 ; i<blockList.get(i).getEntry(j).numElements() ; k++) {
         {
            blockList.get(i).getEntry(j).doSomethingWith(k).makeIt();
            blockList.get(i).getEntry(j).doSomethingWith(k).giveItToMe();
            blockList.get(i).getEntry(j).doSomethingWith(k).yeahReallyDoIt();
         }
       }
     }
sollte man das jeweilige element "zwischenspeichern"
 

Marco13

Top Contributor
Und jetzt wo ich den Code nochmal lese: Wenn du aus der BlockList ein Element entfernst, solltest du danach
i--;
machen, sonst werden Elemente übersprungen!
 

Leroy42

Top Contributor
Marco13 hat gesagt.:
Man kann davon ausgehen, dass der Compiler das wegoptimiert
Mit Sicherheit nicht! Woher soll denn der Compiler wissen,
was in der get-Methode so alles abgeht (Vielleicht schnell mal
ein paar Tausend Eintragungen in eine Datenbank? :shock: )

Wenn du mit Compiler allerdings den Just-In-Time Compiler meinst,
will ich mich mal nicht soweit aus dem Fenster lehnen; ich hab' keine
Ahnung, ob die auch methodenübergreifend optimieren. ???:L
 

Marco13

Top Contributor
Ich bin davon ausgegangen, dass sich das "get" auf eine ArrayList o.ä bezieht. Und solche "Mini-Methoden" zu "inlinen" schafft vielleicht schon der "normale" Compiler, und der JIT-Compiler mit ziemlicher Sicherheit. Natürlich kann der Aufruf nicht "in jedem Fall" wegoptimiert werden. Es ist ja nichtmal gesagt, dass "get(i)" immer das gleiche Element liefern muss :wink:
 

Leroy42

Top Contributor
Marco13 hat gesagt.:
Und solche "Mini-Methoden" zu "inlinen" schafft vielleicht schon der "normale" Compiler

Und nochmal: Nein! Der normale Compiler kann es nicht schaffen dürfen,
da er sich weder den Quelltext der get-Methode anschaut (Den gibt's oft gar nicht) noch
den bereits compilierten Byte-Code der Methode anschauen darf.
Für ihn ist einzig und allein die Methoden-Signatur (die er der .class-Datei entnimmt)
ausschlaggebend.

Stell' dir vor, du hast mit Java 1.5 ein Programm compiliert, das die
get-Methode benutzt. Nun wird mit Java 1.6 eine vollkommen andere
Implementation der ArrayList ausgeliefert und natürlich auch die
get-Methode entsprechend angepaßt. Das mit Java 1.5 compilierte Programm
würde dann unter Java 1.6 nicht mehr laufen können, wenn der Compiler
die get-Methode ge-inlined hätte. :shock:

Aus diesem Grund darf der Compiler (auch wenn er könnte) nichts inlinen. :noe:

Ich persönlich glaube sogar, daß auch der JIT nichts inlinen darf/kann,
bin mir deshalb aber absolut nicht sicher.

Gibt's hier irgendwo einen JIT-Experten, der uns da aufklären könnte? ???:L
Das jetzt zu :### habe ich leider keine Zeit.
 

Marco13

Top Contributor
Nun - wenn ich schreibe "vielleicht", dann heißt das ungefähr das gleiche wie wenn ich schreibe "vielleicht nicht" :wink:

Jedenfalls habe ich gerade mal einen Testlauf gemacht...
Code:
import java.util.ArrayList;

class ArrayTest
{
    private static final int n = 500;
    private ArrayList<ArrayList<Integer>> array = new ArrayList<ArrayList<Integer>>();

    public static void main(String args[])
    {
    	new ArrayTest();
    }

    public ArrayTest()
    {
        init();
        for (int i=10; i<= 50; i+=10)
        {
    		testA(i);
    		testB(i);
    		testC(i);
		}
    }

    private void init()
    {
        for (int i=0; i<n; i++)
        {
            ArrayList<Integer> al = new ArrayList<Integer>();
            array.add(al);
            for (int j=0; j<n; j++)
            {
                al.add(new Integer(i*j));
            }
        }
    }


    private void testA(int runs)
    {
        long startTime = System.nanoTime();
        long result = 0;

		for (int k=0; k<runs; k++)
		{
			for (int i=0; i<array.size(); i++)
			{
				for (int j=0; j<array.get(i).size(); j++)
				{
					result += array.get(i).get(j).intValue() +
							  array.get(i).get(j).intValue() *
							  array.get(i).get(j).intValue();
				}
			}
		}

        long estimatedTime = System.nanoTime() - startTime;
        System.out.println("not stored "+result+ " average time "+(float)estimatedTime/runs/1000000+" ms");
    }


    private void testB(int runs)
    {
        long startTime = System.nanoTime();
        long result = 0;

		for (int k=0; k<runs; k++)
		{
			int size0 = array.size();
			for (int i=0; i<size0; i++)
			{
				ArrayList<Integer> a = array.get(i);
				int size1 = a.size();
				for (int j=0; j<size1; j++)
				{
					Integer v = a.get(j);
					result += v.intValue() + v.intValue() * v.intValue();
				}
			}
		}

        long estimatedTime = System.nanoTime() - startTime;
        System.out.println("stored     "+result+ " average time "+(float)estimatedTime/runs/1000000+" ms");
    }

    private void testC(int runs)
    {
        long startTime = System.nanoTime();
        long result = 0;

		for (int k=0; k<runs; k++)
		{
			for (int i=0; i<array.size(); i++)
			{
				ArrayList<Integer> a = array.get(i);
				for (int j=0; j<a.size(); j++)
				{
					Integer v = a.get(j);
					result += v.intValue() + v.intValue() * v.intValue();
				}
			}
		}

        long estimatedTime = System.nanoTime() - startTime;
        System.out.println("usual      "+result+ " average time "+(float)estimatedTime/runs/1000000+" ms");
    }

}


... und die Ergebnisse sind ziemlich eindeutig (JRE 1.6.0 b105)


Code:
Ohne JIT

not stored 405162376934800 average time 271.64194 ms
stored     405162376934800 average time 70.630066 ms
usual      405162376934800 average time 74.91389 ms
not stored 810324753869600 average time 273.24643 ms
stored     810324753869600 average time 81.826355 ms
usual      810324753869600 average time 74.64223 ms
not stored 1215487130804400 average time 274.09073 ms
stored     1215487130804400 average time 80.40213 ms
usual      1215487130804400 average time 74.216965 ms
not stored 1620649507739200 average time 273.9181 ms
stored     1620649507739200 average time 79.162605 ms
usual      1620649507739200 average time 76.7268 ms
not stored 2025811884674000 average time 274.98007 ms
stored     2025811884674000 average time 80.31631 ms
usual      2025811884674000 average time 75.060104 ms


Mit JIT

not stored 405162376934800 average time 14.466778 ms
stored     405162376934800 average time 4.2331305 ms
usual      405162376934800 average time 3.9609888 ms
not stored 810324753869600 average time 13.623138 ms
stored     810324753869600 average time 3.7420452 ms
usual      810324753869600 average time 3.4562316 ms
not stored 1215487130804400 average time 13.280036 ms
stored     1215487130804400 average time 3.2777224 ms
usual      1215487130804400 average time 3.3728511 ms
not stored 1620649507739200 average time 13.324659 ms
stored     1620649507739200 average time 3.2792883 ms
usual      1620649507739200 average time 3.3646226 ms
not stored 2025811884674000 average time 13.27716 ms
stored     2025811884674000 average time 3.274062 ms
usual      2025811884674000 average time 3.3679144 ms

Wenn man die Array-Elemente zwischenspeichert wird es (egal ob mit oder ohne JIT) schon DEUTLICH schneller (Das teuerste bei den ArrayList-Zugiffen ist aber mit Sicherheit die Bounds-Abfrage, und die spart man sich dann halt ziemlich oft). Das Zwischenspeichern der Arraygröße bringt aber fast nichts.

Zumindest bekräftigen die Zahlen teilweise das, was Leroy42 gesagt hat: Er kann es scheinbar nicht komplett wegoptimieren. (Und die Argumente waren auch VOR diesem Test schon überzeugend). Aber WAS genau der JIT dann noch macht, damit das ganze nochmal um den Faktor 20 (!!!) schneller wird, möge der potentielle JIT-Experte beantworten...
 

Chris_1980

Bekanntes Mitglied
OK, davon hab ich schonmal gehört, aber wenn der ein Teil der VM ist, wie kann man das dann ein oder ausschalten? :bahnhof:
 

Marco13

Top Contributor
Standardmäßig ist er AN. Wenn man aber mit
java -Xint MeinProg
startet, wird er ausgeschaltet. (*gähn* :wink: )
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
O PDF auslesen und verändern, was ist besser iText oder PDFBox ? Allgemeine Java-Themen 9
B Klassen Objekt erzeugen und Konstruktor aufrufen - Welche Lösung ist besser? Allgemeine Java-Themen 2
C Mouse Bereiche - Besser notieren - Tipps Allgemeine Java-Themen 2
R LinkedList und Threads - welche Methode ist besser? Allgemeine Java-Themen 2
J Drei Bedingungen -> 9 Fällen, welcher Ansatz besser Allgemeine Java-Themen 4
F Objekte oder besser ID in Listen speichern? Allgemeine Java-Themen 2
R Gibt es eine JVM, die besser mit dem Speicher umgeht? Allgemeine Java-Themen 7
F Viele generische Parameter sinnvoll? oder besser casten? Allgemeine Java-Themen 10
M Generics - besser programmieren, Warnung umgehen Allgemeine Java-Themen 4
L LeerZeichen besser zu kontrollieren Allgemeine Java-Themen 3
N Lwjgl 3d Objekt wird schmaler, wenn es sich dreht Allgemeine Java-Themen 0
B Ein Objekt einer Klasse mehreren anderen Klassen zur Verfügung stellen? Allgemeine Java-Themen 6
T Objekt Array Aufgabe mit Busdatenbank Allgemeine Java-Themen 2
Maxi-JOO Klassen Dummy Objekt in anderen Constructor übergeben Allgemeine Java-Themen 5
el_niiinho13 Objekt auf der Konsole ausgeben lassen Allgemeine Java-Themen 8
d.lumpi Aus Einer Klasse auf ein Objekt einer anderen Klasse Zugreifen Allgemeine Java-Themen 1
A Objekt aus anderen Objekten machen Allgemeine Java-Themen 8
SaftigMelo In einem Winkel Objekt bewegen Allgemeine Java-Themen 2
E Datentypen Wie kann ich die Längen der unterschiedlichen Ebenen aus einem Objekt lesen von dem ich weiß, dass es ein mehrdimensionaler Array ist? Allgemeine Java-Themen 3
H Objekt speichern und laden Allgemeine Java-Themen 1
H Objekt speichern und laden Allgemeine Java-Themen 1
J Objekt in Bytestream umwandeln Allgemeine Java-Themen 12
J Wie kann ich von Vornherrein einen Fokus auf ein Objekt entfernen? Allgemeine Java-Themen 3
J Information von getSource() Objekt auslesen Allgemeine Java-Themen 1
Drachenbauer Wie stelle ich fest, ob ein Objekt in meinem Array vorkommt? Allgemeine Java-Themen 5
S Variable als Objekt Name Allgemeine Java-Themen 3
D Input/Output Zwischen zwei ID-Räumen unterscheiden und Objekt löschen Allgemeine Java-Themen 16
L Objekt aus Objekt-array "löschen" Allgemeine Java-Themen 2
T Objekt mit String und Int aus TxT Datei erstellen Allgemeine Java-Themen 23
T Objekt in Array packen Allgemeine Java-Themen 6
K Methodenaufruf mit String / String zu Objekt konvertieren Allgemeine Java-Themen 8
S Neues Objekt darstellen Allgemeine Java-Themen 4
J Best Practice Objekt an alle Klassen verteilen ( Discord Bot ) Allgemeine Java-Themen 7
D Objekt-Suche mit mehreren optionalen Parametern Allgemeine Java-Themen 6
M Klassen Objekt weiter geben Allgemeine Java-Themen 1
L Variablen Eigenes Objekt wie z.B. einen Integer zuweisen Allgemeine Java-Themen 3
D Konstruktor - jedes Objekt einzeln erzeugen - alternative? Allgemeine Java-Themen 8
S Applet Überprüfen ob ein Objekt angeklickt wurde Allgemeine Java-Themen 2
RalleYTN 3D Objekt Translation basierend auf Rotation (Probleme mit Z Rotation) Allgemeine Java-Themen 0
B Von String zu <Objekt> ||Speichern/Laden Allgemeine Java-Themen 17
G Neues Objekt aus List<JsonObject> mit Stream Allgemeine Java-Themen 4
P Threads Objekt im Konstruktor anders wie im Run()-Block Allgemeine Java-Themen 10
R Objekt funktioniert nicht auf iOS Allgemeine Java-Themen 15
K Textdatei als Objekt Allgemeine Java-Themen 4
Viktim Classenname zu Objekt Allgemeine Java-Themen 4
P Entity Objekt Methoden vs Service methoden Allgemeine Java-Themen 2
D Datentypen Klassenattribut aus Objekt in generischer Liste Allgemeine Java-Themen 15
O Klassen Bruch im gleichen Objekt Speichern Allgemeine Java-Themen 1
P Liste zu Objekt umwandeln Allgemeine Java-Themen 4
C Liste checken auf MINDESTENS ein Objekt | Bukkit Allgemeine Java-Themen 3
K Best Practice JFrame Objekt allgemein zugänglich machen Allgemeine Java-Themen 8
B ArrayList in ein Objekt legen Allgemeine Java-Themen 1
D Objekt entlang eines Funktionsgraphens bewegen Allgemeine Java-Themen 6
M Objekt serialisieren/deserialisieren und in einer SQLite-Datenbank speichern Allgemeine Java-Themen 3
D Java Objekt als Service in Runtime registrieren Allgemeine Java-Themen 1
S Interaktion mit einer website (website als Objekt?) Allgemeine Java-Themen 3
J OOP Überwachen, ob ein Objekt erzeugt wird Allgemeine Java-Themen 9
S Byte Array welches in Laufzeit aufgelöst wird // Objekt Array Allgemeine Java-Themen 3
Thallius Hash über serialisiertes Objekt? Allgemeine Java-Themen 3
Developer_X Input/Output Serialisiertes Objekt speichern und laden Allgemeine Java-Themen 1
C Generics Objekt in ArrayList Allgemeine Java-Themen 2
L Klassen Konstruktor soll Objekt anderer Klasse erzeugen Allgemeine Java-Themen 2
F Neues Objekt aus .CSV definition Allgemeine Java-Themen 3
K Methoden Objekt wird nicht erkannt Allgemeine Java-Themen 11
P Objekt mit verschiedenen Datentypen Allgemeine Java-Themen 5
T Objekt kontaktiert seinen "erzeuger" Allgemeine Java-Themen 5
S Objekt orientierte Programmierung Allgemeine Java-Themen 7
C Objekt Datenverlust nach Methodenaufruf Allgemeine Java-Themen 9
H JavaFX Von einer Methode auf stage-Objekt zugreifen Allgemeine Java-Themen 3
T WeakReference/PhantomReference: Mitbekommen WELCHES Objekt nun GC'ed wird Allgemeine Java-Themen 2
T Class-Objekt mit URLClassloader Allgemeine Java-Themen 7
P Konsoleneingabe übernehmen und Objekt instanzieren. Allgemeine Java-Themen 5
E Auf Java-Objekt aus anderer Instanz zugreifen Allgemeine Java-Themen 26
L Klassen Polymorphie:2 Attribute gleichen Namens in einem Objekt Allgemeine Java-Themen 6
P Objekt Array in Datei Speichern Allgemeine Java-Themen 3
F Dynamisch ein Objekt einer bestimmten Subklasse erstellen Allgemeine Java-Themen 7
D Player Objekt - Frame über Server anzeigen lassen. Allgemeine Java-Themen 3
V Objekt löschen Allgemeine Java-Themen 7
A OOP Wie auf Objekt der Superklasse zugreifen? Allgemeine Java-Themen 6
S Datei in File-Objekt mit UTF-8 einlesen Allgemeine Java-Themen 2
M neues Objekt speichern, nicht Referenz Allgemeine Java-Themen 10
B synchronisierter zugriff auf Objekt Allgemeine Java-Themen 6
F Objekt einer Datei verschieben, aber Verzeichnispfad fehlt Allgemeine Java-Themen 6
C Objekt Typ herausfinden Allgemeine Java-Themen 5
E Objekt beim Erzeugen in ArrayList Allgemeine Java-Themen 9
M Objekt prüfen auf null ->Invocation Target Exception??? Allgemeine Java-Themen 2
M Objekt aus Liste in Liste suchen/löschen Allgemeine Java-Themen 6
D Eigenen Objekt Pool Allgemeine Java-Themen 15
C blueJ: Objekt wird nicht in Objektleiste angezeigt Allgemeine Java-Themen 8
T Objekt 2x deserialisieren, aber nur 1x im Heap haben? Allgemeine Java-Themen 4
sambalmueslie Benachrichtigung bei neuer Objekt-Instanz Allgemeine Java-Themen 5
U Konstante in Objekt definieren Allgemeine Java-Themen 6
D this mit Objekt überschreiben Allgemeine Java-Themen 17
R Synchronized - auf welchem Objekt Allgemeine Java-Themen 16
E Objekt erstellen Allgemeine Java-Themen 7
M Timer von nicht existiertem Objekt stopen Allgemeine Java-Themen 5
M Swing-Frontend abhängig von ausgewähltem Objekt Allgemeine Java-Themen 4
J Lebt das Objekt noch?? Allgemeine Java-Themen 12
K Objekt einer konkreten Implementierung eines Interfaces durch übergebenen String Allgemeine Java-Themen 2
K Objekt-Austausch zwischen zwei Programmen über System-Clipboard Allgemeine Java-Themen 5

Ähnliche Java Themen

Neue Themen


Oben