Autor |
Beitrag |
Gausi
      
Beiträge: 8548
Erhaltene Danke: 477
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Di 08.02.05 11:39
Ich schreibe grad ein kleines Spielchen, bei dem von oben Sachen runterfallen, die man im Fallen anklicken muss.
Die "Sachen" sind im Wesentlichen TImages, die aber weitere Eigenschaften wie z.B. Geschwindigkeit haben. Der Konstruktor sieht so aus:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| constructor TBierflasche.create; var resStream: Tresourcestream; begin inherited; Speed:= 3; Bild:=TImage.Create(Form1); Bild.Parent:=Form1.MainPanel; case Random(100) of [...] else begin resStream:= TResourceStream.CreateFromID(HInstance, 200, RT_RCDATA); PWert:=100; LWert:=0; end; end; Bild.Picture.Bitmap.LoadFromStream(ResStream); resStream.Free; Bild.Left:=random(Form1.MainPanel.Width-120); Bild.OnMouseDown:=Form1.IMAGEMouseDown; end; |
Das Erzeugen hab ich zu Testzwecken ins OnIdle-Event gepackt
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
| if (random(100) < 5) then begin Bierflasche:=TBierflasche.create; FlaschenListe.Add(Bierflasche); end; for i:=FlaschenListe.Count-1 downto 0 do begin Bierflasche:=FlaschenListe[i] as TBierflasche; if Bierflasche.Bild.Top<200 then Bierflasche.Bild.Top:=Bierflasche.Bild.Top + Bierflasche.Speed else begin if Bierflasche.PWert>=0 then begin dec(Leben); [...] end; Bierflasche.Bild.Picture.Assign(Nil); FlaschenListe.Delete(i); end; end; |
Dieses Stück Code wird also ständig wiederholt. In 5% (random(100)<5) der Fälle wird ein neues Item erzeugt, und wenn es unten angekommen ist, wird es wieder entfernt.
Problem ist: Das wird immer langsamer. Am Anfang flutschen die Bilder richtig flott von oben nach unten, aber nach einiger Zeit....ne.
Die Anzahl der Items bleibt konstant ungefähr bei 10, die Speicherauslastung bleibt laut Taskmanager bei etwa 4.5MB.
Jemand ne Idee, warum die Geschwindigkeit im während der Programmlaufzeit so extrem abnimmt?
_________________ We are, we were and will not be.
|
|
AXMD
      
Beiträge: 4006
Erhaltene Danke: 7
Windows 10 64 bit
C# (Visual Studio 2019 Express)
|
Verfasst: Di 08.02.05 11:44
Sieht stark danach aus, als würdest du irgendetwas nicht freigeben... tippe stark auf
Delphi-Quelltext 1:
| Bierflasche:=TBierflasche.create; | (zweites Codeschnipsel)
AXMD
|
|
Gausi 
      
Beiträge: 8548
Erhaltene Danke: 477
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Di 08.02.05 12:06
Aargghhhh... Hatte zwar den Destructor geschrieben, aber der wurde nicht richtig aufgerufen, weil ich override vergessen hatte..
Jetzt scheint alles in Ordnung zu sein, danke!
_________________ We are, we were and will not be.
|
|
Tino
      

Beiträge: 9839
Erhaltene Danke: 45
Windows 8.1
Delphi XE4
|
Verfasst: Di 08.02.05 12:10
...und im Destruktor von TBierflasche nicht vergessen die Variable Bild freizugeben.
|
|
Gausi 
      
Beiträge: 8548
Erhaltene Danke: 477
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Di 08.02.05 12:13
Das hatte ich schon: Delphi-Quelltext 1: 2: 3: 4: 5:
| destructor TBierflasche.destroy; begin Bild.Free; inherited destroy; end; | Trotzdem danke!
_________________ We are, we were and will not be.
|
|
MitschL
      
Beiträge: 211
Win 98 SE, Win 2000
D5 Pers, D6 Pers und D7 Pro
|
Verfasst: Di 08.02.05 13:18
Ähm,
irgendwie bleibt mir bei den Auswirkungen der Sinn verborgen. Wenn ich etwas nicht freigebe, dann steigt mein Speicherbedarf im Laufe der Programmarbeit (so eigene Erfahrungen), was dazu führen kann, daß das Programm u.U. langsamer läuft.
Nun bleibt aber das Programm hier wohl gleich groß und trotzdem wird es langsamer, weil wegen nicht destruierten Bierflaschen?
Kann mir das mal einer näher bringen?
gegrüßt!
_________________ "Bloßes Ignorieren ist noch keine Toleranz." (Theodor Fontane)
|
|
Udontknow
      
Beiträge: 2596
Win7
D2006 WIN32, .NET (C#)
|
Verfasst: Di 08.02.05 13:43
Poste doch bitte mal die Klassendeklaration.
Cu,
Udontknow
|
|
Gausi 
      
Beiträge: 8548
Erhaltene Danke: 477
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Di 08.02.05 14:18
Da ist eigentlich nichts besonderes bei:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| TBierFlasche = class(TObject) Bild:Timage; Speed:integer; PWert:integer; LWert:integer; constructor create; destructor destroy; override; end; |
Warum das jetzt besser klappt, weiss ich auch nicht genau. Fakt ist, dass ohne das 'override' der Destructor bei FlaschenListe.delete(i) nicht aufgerufen wird. Außerdem reagieren dann einige 'Flaschen' nicht auf OnMouseDown, oder erst dann, wenn man eine andere vorher wegklickt.
_________________ We are, we were and will not be.
|
|
Udontknow
      
Beiträge: 2596
Win7
D2006 WIN32, .NET (C#)
|
Verfasst: Di 08.02.05 14:47
Es hätte ja sein können, das "Bild" eine globale Variable wäre...
So sehe ich erst mal auch nichts. Aber was Optimierung angeht: Wieso ziehst du immer wieder für jede Instanz das Bitmap als Resource? Wäre es nicht effektiver, einmal bei Start eine Bitmapliste zu erstellen und einfach dann das Bitmap über einen Index zu referenzieren und auf die Komponente zu zeichnen, anstelle für jede TBierflasche-Instanz ein Bitmap im Speicher zu halten?
Cu,
Udontknow
|
|
Udontknow
      
Beiträge: 2596
Win7
D2006 WIN32, .NET (C#)
|
Verfasst: Mi 09.02.05 16:54
Woran hat´s denn nun gelegen?
Cu,
Udontknow
|
|
Gausi 
      
Beiträge: 8548
Erhaltene Danke: 477
Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
|
Verfasst: Mi 09.02.05 17:10
Keine Ahnung. Behoben wurde das Problem auf jeden Fall durch 'Override' des Destructors. Zu deinem Vorschlag: Das tut sich nicht viel. Die Bitmaps sind ziemlich klein (90x90), ich habe ca. 7 verschiedene Grafiken, und so gut wie nie mehr als 15 Flaschen gleichzeitig erzeugt. Da ist die Speicherersparnis nicht so riesig, als dass sich der Aufwand des Umcodens für dieses kleine Spielchen lohnen würde.
_________________ We are, we were and will not be.
|
|