|
C#-Quelltext
|
1
2
3
4
5
6
|
if (pickup == null)
{
i--; //somehow this code turns loop into infinite loop
Debug.Log($"null at {pos} with iteration count: {i}");
continue;
}
|
Da ich nicht genug über die Daten in deinem Spiel weiß, kann ich es nicht beurteilen... aber, bist du dir wirklich sicher, dass du hier "
i--;" machen möchtest?
Angenommen an dieser Stelle des Codes hätte
i den Wert
27. Dann machst du
i-- wodurch es dann
26 wird. Danach erfolgt "
countinue". Was dazu führt das sofort das Programm wieder oben bei for, den nächsten Schleifendurchlauf beginnt. Es wird also for(... ;
i++) ausgeführt, und die Schleife wird mit "
i = 27" erneut durchlaufen. Ich kann es nicht beurteilen... ist das wirklich deine Absicht?
Besonders weil ...
Deine Abbruchbedingung ist "i < max" ... und max = size.x * size.y;
Ist dir klar wie lange er versucht ERFOLGREICH (also ohne in
i--; countinue rein zu rutschen) die Schleife zu durchlaufen?
Sagen wir mal size.x ist 15 und size.y ist 10. Dann wäre max = 150.
Er würde also nicht 150x die Schleife durchlaufen, sondern so oft bis er 150 mal ERFOLGREICH war (ohne i--;
countinue). Und beim letzten Teil das er finden könnte, wäre die Chance das Random das richtige bringt nurnoch 1 zu 149! Bedeutet, beim letzten zu findenden Get() wird er mit Random extrem ineffizient sein.
Bedeutet, er wird viel viel öfter die Schleife durchlaufen als nur die 150x. Und wenn er es nicht schaft 150x erfolgreich mit "pickup = PLACING_MAP.GetTile<ItemTile>(pos);" ein Teil zu erhalten (weil es weniger als 150 zu findende Teile gibt), dann wird er niemals fertig! Dein infinite loop?
Das ist so ineffizient, da wäre sogar dann dies hier effizienter:
|
C#-Quelltext
|
1
2
3
4
5
6
7
8
|
for(int y = 0 ; y < size.y ; ++y)
for(int x = 0 ; x < size.x ; ++x) {
var pos = new GridCell(x, y, 0);
var pickup = PLACING_MAP.GetTile<ItemTile>(pos);
if(pickup == null)
continue;
}
|
In diesem Beispiel würde er zwar immer ganz genau (size.x * size.y) mal die Schleife durchlaufen (und jedes Feld einzeln prüfen). Aber garantiert nicht öfters als eben ganz genau (size.x * size.y) mal. Und damit würde er praktisch garantiert immer weniger Durchläufe brauchen als bei deiner ursprünglichen Schleife wo er (size.x * size.y) mal ERFOLGREICH sein will + "Fehlschläge wo Random Pos eine Niete gezogen hat".
Zur optimierung würde ich dann eher versuchen, innerhalb der Schleife(n) möglichst wenige Funktionsaufrufe (auch Random ist ein Funktionsaufruf der was kostet) und möglichst wenige 'new' und Codeverwzeigungen (if, else) zu machen.
Wie oft rufst du RemoveAllPickupsOnDeadGround() überhaupt auf? Aufgrund des Namens der Funktion habe ich da so einen verdacht
- Mehrmals je Frame? Also mehrmals in verschiedene Update() -> Dann überlege dir wie du 'das Ergebnis' merken kannst, damit du höchstens noch 1x pro Frame diese Funktion aufrufen musst. DAS wäre dann eine Optimierung die sich wirklich lohnt!
- Jeden Frame genau 1 aufruf von RemoveAllPickupsOnDeadGround() -> Muss das sein? Oder reicht es auch wenn du nur bei bestimmten Ereignissen, dann RemoveAllPickupsOnDeadGround() aufrufst, weil sich Zwischenzeitlich nichts relevantes ändert?
Wenn es nicht anders geht und jeden Frame 1x sein muss ...ok, schade. Dann so wie oben beschrieben, versuchen die for Schleife(n) zu optimieren. Und dann ersteinmal gut sein Lassen. Vermutlich wird es sowieso schon schnell laufen.
- Seltener als 1x jeden Frame? -> Dann Pfeif drauf. Es wird garantiert! schnell genug sein! Jeder weitere Gedanke ist verschwendet. Programmiere lieber an anderen Stellen deines Spiels weiter