Performance beim Tilemap malen #347

Closed
opened 2026-10-07 15:02:17 +02:00 by admin · 3 comments

Wenn ich zum Malen in einer etwas größeren Tilemap beginne (siehe Project Garden of Sacrifices), dann gehen die FPS stark runter.

Wenn ich zum Malen in einer etwas größeren Tilemap beginne (siehe Project Garden of Sacrifices), dann gehen die FPS stark runter.
admin added the high-priority label 2026-10-07 15:02:17 +02:00
admin added this to the Development project 2026-10-07 15:02:17 +02:00
admin moved this to Next in Development on 2026-10-07 15:02:21 +02:00
Owner

Erledigt in 4c7861b, Wiki-Seite Tilemaps (Abschnitt zu #347) in 0e59e37. Laut Rückmeldung läuft das Malen jetzt flüssig.

Woran es lag

Am Pinsel selbst kaum. Das Profil eines Pinselstrichs zeigte vier Ursachen:

  1. Panels haben ihre Labels in jedem Frame neu gezeichnet. Jeder Frame eines Strichs löst eine Vorschau aus, Asset- und Hierarchy-Panel bauten darauf jede Zeile neu, jedes Label wurde ein neuer Text und ein neuer GPU-Upload (2012 Labels in 3 s, in einem Lauf 46 % des Main-Threads). Jetzt behält ListView.setItems gleich aussehende Zeilen.
  2. Die Szene wurde 2- bis 3-mal pro Frame gezeichnet (pro Mauspunkt, in der Vorschau, noch einmal für animierte Kacheln). Jetzt genau einmal pro Frame, gemessen 1,32 → 1.
  3. layoutSymbols rechnete bei jedem Zeichnen die Symbolringe neu. Das Ergebnis wird jetzt gemerkt, solange sich kein Objekt bewegt.
  4. Jede gemalte Zelle las die ganze Map neu (jede Zelle und ihre 8 Nachbarn über String-Schlüssel). Jetzt gibt es einen Zellindex pro Stand: headless 28 → 16 ms pro Zelle bei 60x60, 109 → 49 ms bei 120x120.

Gemessen

Kopie von Garden of Sacrifices (60x60, 3 Ebenen, 50 Objekte), stein2, Chrome:

  • Beim Malen vorher 20 bis 39 fps, jetzt 47,5. Ohne Malen 55 bis 57.

Tests

Unit frame-preview (2 neu)              → grün; Gegenprobe (alter Redraw) 2 rot
Unit tilemap, list-ping, symbol (5 neu) → grün; 5 einzelne Gegenproben je rot
Unit Tiles/Physik/Listen gesamt         → 32 Dateien, 476 grün
e2e 39,40 (melektaus-atx)               → ALL PASSED, 107 Checks (1 neu)
Gate (melektaus-atx)                    → CHECK EXIT 0, 260 Dateien, 4038 Tests
  • Der neue e2e-Check: ein schneller Strich zeichnet die Szene höchstens einmal pro Frame und rendert kein Label neu (gemessen 6 Redraws in 6 Frames). Mit dem alten Verhalten rot: 24 Redraws in 3 Frames.
  • Neuer Test-Hook __gm.sceneRedraws().

Was bleibt

Eine gemalte Zelle rechnet Kacheln und Kollisionsform der ganzen Map weiterhin neu. Das wächst mit der Map-Größe: bei 60x60 kein Problem mehr, bei deutlich größeren Maps ruckelt es wieder. Die Lösung wäre, nur die geänderten Zellen neu zu rechnen. Dafür gibt es noch kein eigenes Issue.

Erledigt in 4c7861b, Wiki-Seite *Tilemaps* (Abschnitt zu #347) in 0e59e37. Laut Rückmeldung läuft das Malen jetzt flüssig. ## Woran es lag Am Pinsel selbst kaum. Das Profil eines Pinselstrichs zeigte vier Ursachen: 1. **Panels haben ihre Labels in jedem Frame neu gezeichnet.** Jeder Frame eines Strichs löst eine Vorschau aus, Asset- und Hierarchy-Panel bauten darauf jede Zeile neu, jedes Label wurde ein neuer Text und ein neuer GPU-Upload (2012 Labels in 3 s, in einem Lauf 46 % des Main-Threads). Jetzt behält `ListView.setItems` gleich aussehende Zeilen. 2. **Die Szene wurde 2- bis 3-mal pro Frame gezeichnet** (pro Mauspunkt, in der Vorschau, noch einmal für animierte Kacheln). Jetzt genau einmal pro Frame, gemessen 1,32 → 1. 3. **`layoutSymbols`** rechnete bei jedem Zeichnen die Symbolringe neu. Das Ergebnis wird jetzt gemerkt, solange sich kein Objekt bewegt. 4. **Jede gemalte Zelle las die ganze Map neu** (jede Zelle und ihre 8 Nachbarn über String-Schlüssel). Jetzt gibt es einen Zellindex pro Stand: headless 28 → 16 ms pro Zelle bei 60x60, 109 → 49 ms bei 120x120. ## Gemessen Kopie von *Garden of Sacrifices* (60x60, 3 Ebenen, 50 Objekte), stein2, Chrome: - Beim Malen vorher 20 bis 39 fps, jetzt 47,5. Ohne Malen 55 bis 57. ## Tests ``` Unit frame-preview (2 neu) → grün; Gegenprobe (alter Redraw) 2 rot Unit tilemap, list-ping, symbol (5 neu) → grün; 5 einzelne Gegenproben je rot Unit Tiles/Physik/Listen gesamt → 32 Dateien, 476 grün e2e 39,40 (melektaus-atx) → ALL PASSED, 107 Checks (1 neu) Gate (melektaus-atx) → CHECK EXIT 0, 260 Dateien, 4038 Tests ``` - Der neue e2e-Check: ein schneller Strich zeichnet die Szene höchstens einmal pro Frame und rendert kein Label neu (gemessen 6 Redraws in 6 Frames). Mit dem alten Verhalten rot: 24 Redraws in 3 Frames. - Neuer Test-Hook `__gm.sceneRedraws()`. ## Was bleibt Eine gemalte Zelle rechnet Kacheln und Kollisionsform der **ganzen** Map weiterhin neu. Das wächst mit der Map-Größe: bei 60x60 kein Problem mehr, bei deutlich größeren Maps ruckelt es wieder. Die Lösung wäre, nur die geänderten Zellen neu zu rechnen. Dafür gibt es noch kein eigenes Issue.
admin moved this to Done in Development on 2026-10-07 16:56:11 +02:00
Owner

Was bleibt (nur die geänderten Zellen neu rechnen) ist jetzt #348.

Was bleibt (nur die geänderten Zellen neu rechnen) ist jetzt #348.
Owner

Nachtrag: Der volle CI-Lauf 304 zu 4c7861b hatte meinen neuen Check e2e 40c-iii rot. Beim Malen wurden die Beschriftungen „Comment“ und „Held“ neu gezeichnet, eine Notiz und eine Gruppe, die e2e 36 in einem Graphen anlegt. Beim Testen von #347 lief 36 nicht davor.

  • Ursache: AnnotationView.redraw() setzte bei jedem Aufruf einen neuen TextStyle, und der offene Graph-Tab zeichnet bei jeder Projektänderung neu. Dieselbe Art Leck wie bei den Panels.
  • Fix in 8154569: Der Stil wird nur neu gesetzt, wenn sich Farbe oder Breite ändern.
  • Tests: Unit annotation-view (neu) 2 grün, Gegenprobe rot. e2e 36,39,40,49 auf atx: der Check grün (redrawnTexts []). Gate grün (4040 Tests).
  • Wiki Tilemaps hat dazu einen Satz (7545d2e).
Nachtrag: Der volle CI-Lauf 304 zu `4c7861b` hatte meinen neuen Check **e2e 40c-iii** rot. Beim Malen wurden die Beschriftungen „Comment“ und „Held“ neu gezeichnet, eine Notiz und eine Gruppe, die e2e 36 in einem Graphen anlegt. Beim Testen von #347 lief 36 nicht davor. - **Ursache:** `AnnotationView.redraw()` setzte bei jedem Aufruf einen neuen `TextStyle`, und der offene Graph-Tab zeichnet bei jeder Projektänderung neu. Dieselbe Art Leck wie bei den Panels. - **Fix** in `8154569`: Der Stil wird nur neu gesetzt, wenn sich Farbe oder Breite ändern. - **Tests:** Unit `annotation-view` (neu) 2 grün, Gegenprobe rot. e2e 36,39,40,49 auf atx: der Check grün (`redrawnTexts []`). Gate grün (4040 Tests). - Wiki *Tilemaps* hat dazu einen Satz (`7545d2e`).
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: meleki/feuerwerk#347