Performance-Verlust mit cloneObject

Started by Telix, November 23, 2013, 10:08:52 PM

Previous topic - Next topic

Telix

Hi zusammen,

was mache ich falsch, wenn ich cloneObject3D nutze, rendert er langsamer als wenn ich alle objekte selber erstelle?
Kann man da was falsch machen oder wie kommt das?

Mit cloneObject ca. 43FPS und ohne ca. 60FPS.

Gruß
Michael

EgonOlsen

Also...wenn du da nicht aus versehen irgendwas doppelt renderst, dann sehe ich keinen Grund für dieses Verhalten und würde es in die Kategorie 'Zufall' einordnen.
Um sicher zu gehen, kannst du mal World.getVisibilityList() ausgeben und schauen, ob die Ergebnisse gleich sind.

Telix

#2
Die Methode getVisibilityList gibt bei android nicht?
Nach meiner Ansicht dürften es passen.

FPS zahl ist ohne CloneObject wirklich besser bei mir :(

Also ich clone ein Objekt und das neue Objekt füge ich World hinzu.
Oder ist das falsch? Wenn ich es nicht hinzufüge kann ich es nicht mehr anzeigen.
Weil ich von jedem Objekt selber die Visbility selbst setze wenn sich die Kamera Position ändern.

EgonOlsen

Ja, stimmt...die Methode habe ich bei Android entfernt, weil sie nur noch bedingt sinnvoll war. Machst du noch irgendwas anderes wie shareCompiledData()? Ich sehe wirklich keinen Grund, wieso das so sein sollte. Kannst du einen einfachen Testfall bauen, der das Problem zeigt?

Telix

Ich hab dir das Projekt geschickt.

Du findest die Stelle unter:
com.sytko.dungeonarena.world.WorldLevel
Zeile 21 -> kannst du den Cache aktivieren.

Vielen Dank
Michael

EgonOlsen

Alles klar. Gucke ich mir morgen mal an. Heute wird das vermutlich nichts mehr.

Telix

Vielen Dank, dass du dir die Zeit nimmst! :) Evtl. findest du ja noch andere no go's von mir :D

EgonOlsen

Also erstmal zwei kleine Anmerkungen zum Code an sich:

In WorldBlock würde ich den Konstruktor ersetzen durch:


public WorldBlock(Object3D obj) {
super(obj, true);
this.shareCompiledData(obj);
}


Das spart Speicher und rendert u.U. etwas schneller.

Und das Rückgängigmachen der Translation in WorldLevel geht so einfacher:


WorldBlocks[y][x] = new WorldBlock(cache);
WorldBlocks[y][x].clearTranslation();


Jetzt aber zum Performanceproblem. Ich habe eine Weile gesucht...ich denke, es liegt daran, dass deine Objekte aus dem Cache teilweise komplexer sind als die, die du neu erstellst. Wenn du neue erstellst, wertest du hasRight, hasLeft usw. aus und erzeugst nur bei Bedarf die entsprechenden Polygone. Wenn du aber immer das gecachte Objekt des jeweiligen Typs nimmst, dann erwischt du das erste erstellte. Und wenn das bei hasRight usw. false hatte, dann hat das Polygone an Stellen, wo dein neu erzeugtes gar keine hätte. Das siehst du auch den Meldungen des ObjectCompilers. Die neu erstellten haben ganz oft 6 Polygone und kompilieren in ein Teilobjekt wo die aus dem Cache 12 Polygone haben und in 2 Teilobjekte kompiliert werden.

Telix

ich cache aber nur die objekte die NUR hasUpper haben. Alle anderen lasse ich normal erzeugen.
Somit müsste es immer nur 2 Polys haben.? Oder habe ich ein Denkfehler?

EgonOlsen

Quote from: Telix on November 25, 2013, 09:04:13 PM
Oder habe ich ein Denkfehler?
Ich denke ja. Du cachst nicht nur die Objekte, die nur hasUpper haben...du erzeugst nur diese aus dem Cache. Im Cache sind aber auch solche, die durchaus mehr als hasUpper haben. Du müsstest dann eher sowas machen wie:


WorldBlocks[y][x] = new WorldBlock(12);
if (_useCache && hasUpper && !hasLower && !hasFront && !hasLeft && !hasRight) {
    _cacheObjects.put(Blocks[y][x], WorldBlocks[y][x]);
}


Sonst landet das erstbeste Objekt dieses Typs im Cache und das hat u.U. mehr als nur Upper.

Telix

Du hast natürlich recht! Das habe ich übersehen...
Nun scheint die Performance ähnlich zu sein (Hoffe es bringt was der Cache)