# Performance



## bob_sheknowdas (14. Jun 2012)

Hi,
ich habe ein Spiel zusammengeschrieben, was so weit fast fertig ist (paar Optimierungen fehlen noch, aber an sich ist es spielbar). 
Bei mir lief das auch immer ganz gut, aber ich habs mal einem Freund geschickt zum testen und er meint bei ihm ruckelt das wie bekloppt.

Ich hab jetzt als Java-Anfänger nicht so die Ahnung von Code- und Performanceoptimierung, deswegen woltl ich hier mal nachfragen. Irgendwie sowas wie die 10 Grundregeln von Performantem Javacode wären gut.

Ich hab schon mal im Netzt nen bischen geschaut und folgendes gefunden.

1. Variablen bei denen das möglich/sinnvoll ist immer final setzen.
2. If-Abfragen so schachteln, dass der wahrscheinlichste Fall möglichst früh eintritt.
3. Anstatt
	
	
	
	





```
a.getb().getc().mach1();
a.getb().getc().mach2();
```
 immer 
	
	
	
	





```
C c = a.getb().getc();
c.mach1();
c.mach2();
```

Das hab ich so weit umgesetzt, hat aber bis jetzt noch nicht den gewünschten Effekt gebracht...
Fallen euch noch mehr solche Grundsätze ein?


----------



## The_S (14. Jun 2012)

Einfacher wäre es, wenn du uns die konkrete Schwachstelle zeigst.


----------



## SlaterB (14. Jun 2012)

die bisher genannten Tipps, also 3. könnten schon was bringen, falls zufällig getc(); erst aufwendig irgendwas berechnet,
dann wären 50% gespart,
dabei gehts aber normalerweise bei diesem Tipp nicht, der ist auch für einfache getter angedacht

allein mit solcher Kosmetik kannst du den Windows-Quellcode von 2 GB auf 300 MB zusammenstampfen, 
es müsste aber dennoch nicht unbedingt schneller laufen

wirklich wichtig für Performance sind inhaltliche Optimierungen, z.B. angezeigte Bilder nicht bei jedem repaint() von der Festplatte neu laden,
sondern am Anfang im Konstruktor als Instanzattribut ablegen, das fällt nicht unter Standardregeln, oder?

poste Code wenn was langsam läuft und erkläre gewisse Abläufe,
untersuche selber, ob mit simplen System.out.println oder Profilern, welche Codeabschnitte wie lange besucht werden


----------



## Firephoenix (14. Jun 2012)

Grundsätzlich zur Performance:
-Gute Algorythmen verwenden
-nur das berechnen was man braucht
-kein "polling" betreiben
-kritische stellen über profiling herausfiltern (google)
-überlegen warum an diesen stellen die meiste rechenzeit verbracht wird und ob man dort optimieren kann.
-Daten auf Vorrat halten (Bilder nicht bei jedem Zeichnen neu von der Platte laden, bei einem Netzwerkspiel nich pro update das gesamte level über das netzwerk an alle Spieler schicken...)
-...

Sicherlich nicht das leichteste Thema, aber ich denke intelligenter Code geht immer über diese Minitricks wie final-Variablen, wenn die Operation in O(n^2) läuft kann man lange tunen, man kommt nie an den Effekt als würde man sie durch eine gleichwertige Operation ersetzen die in O(n* log n) läuft 

Gruß


----------



## bob_sheknowdas (14. Jun 2012)

Firephoenix hat gesagt.:


> Grundsätzlich zur Performance:
> -Gute Algorythmen verwenden
> -nur das berechnen was man braucht
> -kein "polling" betreiben
> ...




bedeutet "polling" auch in meinem threat ständig über if() zu prüfen ob mein Leben > 0 ist?
wenn ja, wie umgeh ich solche Abfragen?


----------



## SlaterB (14. Jun 2012)

denkbar ist, entsprechende Aktionen nur dann zu veranlassen, wenn das Leben geändert wird, gar fällt, 
was ja wohl nicht ganz so häufig der Fall sein wird,

aber ein if auf einfache Variablen, auch regelmäßig, mag vielleicht technisch als Polling zählen,
ist aber nur dann kritisch wenn es wirklich Ressourcen verbraucht, etwa weil jedes if einen Netzwerkzugriff zum Server verursacht

problematisch kann daran sein, eine Schleife ohne Pause zu verwenden, welche Millionen Mal pro Sekunde ausgeführt wird,
einen CPU-Kert auf 100% Auslastung setzt,
20ms Warten reduzieren die Durchläufe dagegen auf 50 pro Sekunde


----------



## bob_sheknowdas (14. Jun 2012)

hmm, also bis jetzt habt ihr nix genannt wo ich mir einer Schuldbewusst wäre...
Es ist für mich auch schwierig zu sagen an welcher Stelle genau es hackt (bei mir läuft ja alles flüssig).
Mein Kumpel meinte nur das Spiel stockt und ich nehme an er meint damit den gesammten Spielablauf...

Was ich sagen kann ist, dass das Programm beim starten etwas länger braucht, aber das liegt daran, dass Bild- und Musikdateien geladen werden müssen...
Ich hatte schon überlegt ob vllt zu große Bilder Ursache des problems sein könnten, aber der PC meines Kumpels spielt 2 Jahre alte Games ohne Probleme (und die sollten doch weit größere Texturen verwenden)...

Ansonsten kann ich euch hier nur mal einen Downloadlink für mein Projekt abieten. Es ist mit java3D geschrieben (die Bibliotheken müsstet ihr euch also ziehen wenn ihr testen wollt).
Die main-Methode befindet sich in der Klasse "Spiel". Nach drücken des Start-Buttons gehts los. Beschleunigen mit Pfeiltasten, Steuerung mit WASD, Waffe wechseln mit Q oder E (erst nachdem Updates [kleine gelbe Kugeln] eingesammelt wurden), Ballern mit Leertaste. Ziel ist das grüne Schiff mit möglichst wenig verbrauchter Munition zu zerhaun...
https://dl-web.dropbox.com/get/SpaceShooter.zip?w=d4a96866


----------



## Gast2 (14. Jun 2012)

Blöde Frage aber was fürn Rechner hat dein Kumpel denn? Ists ne alte Gurke?


----------



## Marco13 (14. Jun 2012)

Der Link ist wohl tot. Aber da du von Bildern redest hat meine Kristallkugel gesagt, dass ich dich auf http://www.java-forum.org/spiele-mu...18-performance-bufferedimages.html#post878295 hinweisen soll....


----------



## bob_sheknowdas (14. Jun 2012)

Marco13 hat gesagt.:


> Der Link ist wohl tot. Aber da du von Bildern redest hat meine Kristallkugel gesagt, dass ich dich auf http://www.java-forum.org/spiele-mu...18-performance-bufferedimages.html#post878295 hinweisen soll....



Hier nochmal nen Alternativlink: Zippyshare.com - SpaceShooter.zip


----------



## Marco13 (14. Jun 2012)

96.38 MB !?


----------



## Evil-Devil (14. Jun 2012)

Marco13 hat gesagt.:


> 96.38 MB !?



er hat sourcecode als auch binaries geliefert und leider die Inhalte nicht davon getrennt. Somit sind Texturen, 3D Modell und Audio doppelt vorhanden. Die Hintergrund Musik schlägt mit 2x ~45,7MB zu Buche.

[ot]Kann Java ohne Beihilfe nicht auch was anderes als WAV wiedergeben?[/ot]


----------



## herdi (15. Jun 2012)

bob_sheknowdas hat gesagt.:


> bedeutet "polling" auch in meinem threat ständig über if() zu prüfen ob mein Leben > 0 ist?



Hast du nur einen Thread laufen? Bei einem Spiel, was in sequentiellen Abfolge läuft, wäre es vllt. sinnvoll mehre Threads zu starten/ beenden. Je nach Bedarf.


----------



## bob_sheknowdas (15. Jun 2012)

herdi hat gesagt.:


> Hast du nur einen Thread laufen? Bei einem Spiel, was in sequentiellen Abfolge läuft, wäre es vllt. sinnvoll mehre Threads zu starten/ beenden. Je nach Bedarf.



An sich ist es nur ein Threat. Aber meine Musik wird in nebenläufigen Threats abgespielt. Das kommt aber nicht von mir, sondern ist eine eigenschaft der play()-Methode...


----------



## ARadauer (15. Jun 2012)

Generell kann man aber sagen, wenn dein Programm nicht flüssig läuft liegt es nicht an den 3 Punkten die do oben beschrieben hast... da hast du schon was anderes falsch gemacht...


----------



## herdi (15. Jun 2012)

bob_sheknowdas hat gesagt.:


> bedeutet "polling" auch in meinem threat ständig über if() zu prüfen ob mein Leben > 0 ist?
> wenn ja, wie umgeh ich solche Abfragen?



Da könnte doch die Theorie des "observer pattern" helfen.
Grobe Architektur könnte da sein: 

Du hast einen Handler, der die Ereignisse behandelt und entsprechend an das Subjekt weiter gibt. 
Dieses gibt die Information(en) mittels "push" weiter an die jeweiligen "Observer". Diese updaten dann ihren Status. Bspw.: die Health Points, Munition, aktuellen Waffentyp etc. 

So vermeidest du u.a. das "polling". Keine zyklischen Abfragen über Änderungen von Objekteigenschaften. 



bob_sheknowdas hat gesagt.:


> An sich ist es nur ein Threat.



Ich habe mir dein Spiel nicht angeschaut. Der Name "Spaceshooter" lässt mich aber erahnen, dass Objekte/ Ereignisse parallel erzeugt werden. Hier mit Threads zu arbeiten wäre sinnvoll, da wie oben beschrieben Objekte/ Ereignisse sequentiell sondern parallel erzeugt werden. Bspw.: Gegner UND Asteroiden. 
Ein weiteres Beispiel: ich arbeite neben meinem Studium als Java Entwickler in einem BI Unternehmen. Dort entwickle ich u.a. Software, die große Datenmengen verwerten/auswerten soll. Natürlich soll der Endbenutzer eine GUI vor sich haben. Hier wird die Datenauswertung und die GUI jeweils in separaten  Threads ausgeführt, da der Algorithmus der Auswertung der Daten parallel starten kann, während sich die GUI aufbaut bzw. umgekehrt.


----------



## Titanpharao (15. Jun 2012)

Hat dein Kumpel vielleicht 64bit Java und du 32bit?

Bei meinem Spiel hat das bei einem auch mal signifikate Unterschiede gemacht, wobei hier das 64bit langsamer war ...


----------



## homer65 (15. Jun 2012)

Bei Performance Problemen gilt generell:
Wenn man die Ursache nicht kennt, wird man das Problem auch nicht beheben.
Einfach irgentwelche Dinge tun, weil sie angeblich gut für die Performance sind, ist stochern im Nebel und führt zu nichts.
Also: Erstmal die Ursache suchen.
Bei Java sind da "Profiler" hilfreich.

Einzige Ausnahme: Schnellere Hardware tuts oft auch.
Da spart man sich den Aufwand der Ursachenforschung, ist die Frage was weniger Aufwand ist.


----------



## Marco13 (15. Jun 2012)

Ja, das läuft hier flott, aber auf einem alten Rechner sieht es vermutlich anders aus. TPTP sagt, dass (wenn man Space oft mal gedrückt hält) playLaser ziemlich teuer ist. Vermutlich solltest du mal die Feuerrate begrenzen. Ansonsten sieht der Rechner nämlich ziemlich gelangweilt aus. 

Das Spiel an sich ... könnte ja ganz lustig sein, aber ersten sind die Pfeiltasten für hoch und runter gerade vertauscht :autsch: und zweitens dreht sich das Schiff so schnell, dass man praktisch nicht zielen kann. Eine Maussteuerung wäre nicht schlecht. (Und mehr Gegner und so, aber das hat damit ja nichts zu tun)


----------



## bob_sheknowdas (18. Jun 2012)

Hmm, naja danke auf jeden Fall für die vielen Antworten  -  ich werd mal schaun was sich damit anfangen lässt...




Marco13 hat gesagt.:


> Das Spiel an sich ... könnte ja ganz lustig sein, aber ersten sind die Pfeiltasten für hoch und runter gerade vertauscht :autsch: und zweitens dreht sich das Schiff so schnell, dass man praktisch nicht zielen kann. Eine Maussteuerung wäre nicht schlecht. (Und mehr Gegner und so, aber das hat damit ja nichts zu tun)



Die Pfeiltasten sind nicht vertauscht. Es ist wie bei einem richtigen Flugzeug: drückst du den Steuerknüppel nach vorne senkt das Flugzeug die Spitze, ziehst du ihn nach hinten steigt es.

Was das schnelle Lenken angeht: ich habe versucht einen Kompromiss zu finden zwischen guer Zielbarkeit und einem hohen Spieltempo. Wenn ich das Lenken verlangsamme nehm ich denk ich recht viel Geschiwindigkeit aus dem Spiel. Aber wie gesagt, ich bin mit der Feinjustierung noch nicht fertig...

Mehr Gegner wären wieder mehr Objekte, die "intelligent" bewegt werden müssten. Das mach tdas Game ja noch langsammer


----------

