AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Performanceproblem: Anzeige von Positionen mehrerer Clients
Thema durchsuchen
Ansicht
Themen-Optionen

Performanceproblem: Anzeige von Positionen mehrerer Clients

Ein Thema von alphaflight83 · begonnen am 20. Dez 2010 · letzter Beitrag vom 14. Feb 2011
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von alphaflight83
alphaflight83

Registriert seit: 5. Jun 2008
Ort: Würzburg
147 Beiträge
 
Delphi 10.4 Sydney
 
#1

Performanceproblem: Anzeige von Positionen mehrerer Clients

  Alt 20. Dez 2010, 14:10
Delphi-Version: 2009
Tag auch,
ich habe momentan ein mittelschweres Anzeige-Performanceproblem.
Und zwar müssen mehrere Clients anhand von Positionsangaben (X, Y, Winkel) auf einer Karte angezeigt
und ihre Pfade aufgezeichnet werden.
Die Daten kommen hierbei zyklisch vom Server.
Nun die Frage(n):
Wie kann ich möglichst ressourcenschonend
1. Mehrere Clients (momentan bis zu 64) bzw. ihre Bewegungen anzeigen
2. den Pfad für diese Clients aufzeichnen (Liste für X und Y Koordinaten im Ringspeicher)
3. Den Pfad für jeweils ein Gerät anzeigen.

Momentaner Stand:
Ad 1. Dynamisch erstellte Frames, die je nach Winkel ein entsprechendes Bild anzeigen.
Bei Bewegung werden die Frames auf einem Panel verschoben.
Ad 2. Zum Aufzeichnen der Pfade wird ein Array
Positions : Array [1 .. 64] of TList; verwendet, das dann Records der Art
Delphi-Quellcode:
TRecPos = record
  Xpos : Integer;
  Ypos : Integer;
  Angle : Integer;
end;
speichert.
TQueue habe ich nicht verwendet, weil ich auf alle Elemente zugreifen muss und TQueue,
soweit ich gesehen habe, eine Eigenschaft wie Items[Index] fehlt.
Ist die Liste voll, werden die Einträge von vorne überschrieben.
Um den momentanen Start-Index für jeden Client zu behalten, wird dieser in einem weiteren Array abgelegt.
Ad 3. Die Pfade werden auf einer über das Panel gelegten Paintbox mit
Delphi-Quellcode:
PaintBox.Canvas.MoveTo(Y1, X1);
PaintBox.Canvas.LineTo(Y2, X2);
angezeigt.
Hierbei wird durch die jeweilige Liste iteriert und von Punkt zu Punkt verbunden.
Grundsätzlich funktioniert das schon,
allerdings ist das Ganze performancetechnisch relativ bescheiden, um es positiv auszudrücken.

Ich bin für jeden sinnvolleren Ansatz bzw. Tipp bzgl. Komponenten, Vorgehensweise etc. dankbar.

Grüße, alphaflight
Make me a sandwich! - What? Make it yourself. - Sudo make me a sandwich! - Okay
  Mit Zitat antworten Zitat
stho

Registriert seit: 16. Sep 2009
Ort: 127.0.0.1
288 Beiträge
 
Delphi 2007 Professional
 
#2

AW: Performanceproblem: Anzeige von Positionen mehrerer Clients

  Alt 20. Dez 2010, 14:46
Wo liegt denn genau der Flaschenhals?
Beim Zeichnen oder beim Senden/Empfangen?
Vielleicht solltest du nicht das komplette Array an jeden Client senden sondern nach dem Empfangen der Werte prüfen welche sich geändert haben und diese dann an die Clienten verteilen?
Sendest du das komplette array in einem Rutsch an die Clienten oder nur die einzelnen records in einer Schleife?
Zeichnen solltest du auf ein unsichtbares bitmap und dann mittels "BitBlt" auf deine Paintbox (oder ein TImage?) übertragen...

(Bei mir lasse ich ein Array von 1.000.000 Records durchlaufen und regelmäßig neuzeichnen...
mit dieser Methode geht das ziemlich schnell!)
  Mit Zitat antworten Zitat
Benutzerbild von alphaflight83
alphaflight83

Registriert seit: 5. Jun 2008
Ort: Würzburg
147 Beiträge
 
Delphi 10.4 Sydney
 
#3

AW: Performanceproblem: Anzeige von Positionen mehrerer Clients

  Alt 20. Dez 2010, 15:39
Hallo stho,

erstmal danke für die Antwort.
Der Flaschenhals ist wohl ein mehrfacher.

Schon beim Einschalten des Positions-"Loggens" sind Einbrüche zu verzeichnen,
die beim Pfadzeichnen dann noch verstärkt werden.

Das größte Problem ist anscheinend allerdings die Anzeige bzw. das Verschieben der Frames mit den winkelabhängig unterschiedlichen Bildern.
Hier ist bei einer Zunahme der Framezahl ein deutlicher Einbruch spürbar.

Ich werde morgen mal die vorgeschlagene Zeichenmethode ausprobieren.
Ich denke aber, dass zusätzlich die Änderung des Lese-Schreib Vorganges unumgänglich ist.
Make me a sandwich! - What? Make it yourself. - Sudo make me a sandwich! - Okay
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#4

AW: Performanceproblem: Anzeige von Positionen mehrerer Clients

  Alt 20. Dez 2010, 17:26
vielleicht hilft Dir das
http://www.delphipraxis.net/156716-g...-und-zoom.html
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Benutzerbild von alphaflight83
alphaflight83

Registriert seit: 5. Jun 2008
Ort: Würzburg
147 Beiträge
 
Delphi 10.4 Sydney
 
#5

AW: Performanceproblem: Anzeige von Positionen mehrerer Clients

  Alt 21. Dez 2010, 08:28
Hi Bummi,
danke für den Link.

Im Thread schreibst du, dass das nicht deine präferierte Methode zur Animation ist ...
Nun, was würdest du mir denn für meine Anwendung empfehlen?
Mir geht es um eine möglichst flüssige Ausgabe bei maximaler Performance.

Dazu muss ich sagen, dass ich erste Versuche mit Andorra gemacht habe,
in meiner Anwendung neben dieser Anzeige aber gleichzeitig auch andere "Module" laufen können/müssen.
Das Positionsmodul mit Andorra lief nun einigermaßen flüssig, der Rest bekam aber kaum noch Rechenzeit ab ...

Zudem hat sich hier das Problem gestellt, wie man das einigermaßen vernünftig in Threads verpacken kann,
da in jedem Modul relativ viel wieder angezeigt werden muss.
Make me a sandwich! - What? Make it yourself. - Sudo make me a sandwich! - Okay

Geändert von alphaflight83 (21. Dez 2010 um 08:46 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Bummi
Bummi

Registriert seit: 15. Jun 2010
Ort: Augsburg Bayern Süddeutschland
3.470 Beiträge
 
Delphi XE3 Enterprise
 
#6

AW: Performanceproblem: Anzeige von Positionen mehrerer Clients

  Alt 21. Dez 2010, 13:21
Was meinst Du mit Clients und anderen Modulen, was ist unter Positions-"Loggen" zu verstehen?
Können die Daten gethreaded gesammelt werden, könntest Du mit Canvas.Lock eine Offscreenbitmap mit allen Clientpositionen in einem Thread erstellen.
Thomas Wassermann H₂♂
Das Problem steckt meistens zwischen den Ohren
DRY DRY KISS
H₂ (wenn bei meinen Snipplets nichts anderes angegeben ist Lizenz: WTFPL)
  Mit Zitat antworten Zitat
Benutzerbild von alphaflight83
alphaflight83

Registriert seit: 5. Jun 2008
Ort: Würzburg
147 Beiträge
 
Delphi 10.4 Sydney
 
#7

AW: Performanceproblem: Anzeige von Positionen mehrerer Clients

  Alt 21. Dez 2010, 16:33
Das Programm beinhaltet mehrere Teilbereiche, die Positionsanzeige ist also nur eine Funktion unter vielen,
von denen mehrere gleichzeitig laufen können müssen.

Mit Positionsloggen meinte ich, dass die Positionsdaten der Clients über einen gewissen Zeitraum gesammelt werden.
Angezeigt werden kann, der Übersicht wegen, immer nur der Pfad eines Clients.

Das mit dem Offscreenbitmap ist keine schlechte Idee und sollte funktionieren.
Damit und mit GDI werde ich mich mal näher befassen.

Danke schön für den Tipp.
Make me a sandwich! - What? Make it yourself. - Sudo make me a sandwich! - Okay
  Mit Zitat antworten Zitat
Benutzerbild von alphaflight83
alphaflight83

Registriert seit: 5. Jun 2008
Ort: Würzburg
147 Beiträge
 
Delphi 10.4 Sydney
 
#8

AW: Performanceproblem: Anzeige von Positionen mehrerer Clients

  Alt 20. Jan 2011, 15:16
So, ich bin mal wieder bei diesem Thema gelandet ... und dank der Tipps von Bummi bin ich ein Stück weiter gekommen.
Das Offscreenbitmap funktioniert grundsätzlich und ich habe die verlinkten Sprites verwendet um die Clients anzuzeigen.
Abgesehen von ein paar Details habe ich nun ein Problem:
Ich möchte die Sprites eigentlich mit auf das Offscreenbitmap packen, nur hat sich mir bisher nicht erschlossen,
wie ich die gedrehten Sprites da rauf bekomme, bzw. ob das so überhaupt möglich ist.
Oder anders formuliert: Wie kann ich performant ein Bitmap drehen um es dann auf das Offscreenbitmap zu kopieren.
(In der Endanwendung sollen um die 60 Clienten angezeigt werden.)

Zudem hab ich bisher noch nicht gerafft, wie ich ein Bitmap/Image komplett "löschen", also auf komplette Transparenz zurücksetzen kann.
Edit: Hab einen Thread zum Leeren von Offscreenbitmaps gefunden, in dem Möglichkeiten aufgezeigt werden.

Grundsätzlich ist das Vorgehen doch richtig, die Position und Ausrichtung aller Clienten zu ermitteln und nacheinander auf ein Offscreenbitmap zu zeichnen,
das dann wiederum nach dem Hintergrund-Offscreenbitmap auf das Canvas gezeichnet wird?!?
Das Positions-Offscreenbitmap wollte ich dann zyklisch neu zeichnen um die Positionen anzupassen ...

Hab mich jetzt auch mal an GDI+ rangewagt (Mit der Version von Erik van Bilsen) Allerdings gibt es hier noch einige Unklarheiten.
(z.B. Kann man ein Objekt "Auf der Stelle" rotieren, ohne dass durch RotateTransform das Koordinatensystem für ein TranslateTransform verschoben wird?)

Grüße, alphaflight83
Make me a sandwich! - What? Make it yourself. - Sudo make me a sandwich! - Okay

Geändert von alphaflight83 (21. Jan 2011 um 10:00 Uhr) Grund: Thread "Leeren von Offscreenbitmaps" gefunden
  Mit Zitat antworten Zitat
Benutzerbild von alphaflight83
alphaflight83

Registriert seit: 5. Jun 2008
Ort: Würzburg
147 Beiträge
 
Delphi 10.4 Sydney
 
#9

AW: Performanceproblem: Anzeige von Positionen mehrerer Clients

  Alt 11. Feb 2011, 09:52
So, ich glaube ich habe nun das Ergebnis, das ich haben wollte.

Zunächst mal hab ich einen Zwischenschritt beim Zeichnen weggelassen der keinen Sinn machte
und zeichne nun alles auf EIN Offscreenbitmap.

Mit GDIPlus hab ich nun auch bei den rotierten Images ein zufriedenstellendes Ergebnis erzielt.

Anmerkungen:
Der Beispiel-Code verwendet kein Offscreenbitmap.
Die Bilsen GDIPlus Implementation verwendet Objekt-Interfaces.

Delphi-Quellcode:
uses GDIPlus;

procedure TFormDrawThis.DrawImages;
var
  Graphics: IGPGraphics;
  Image: IGPImage;
  Matrix: IGPMatrix;
  imgWidth, imgHeight : Integer;
  Angle : Single;
begin
  (* Lock the canvas *)
  Canvas.Lock;

  (* Get the dimensions of the bitmap *)
  imgWidth := Image.GetWidth;
  imgHeight := Image.GetHeight;
   
  (* Create the GDIPlus components *)
  Graphics := TGPGraphics.Create(Canvas.Handle);
  Image := TGPImage.Create(sImage_Path + 'AwesomeImage.png', TRUE);
  (* Create the transformation matrix *)
  Matrix := TGPMatrix.Create;

  (* Set the transformation *)
  Angle := 30.0;
  Matrix.Translate(150, 100);
  Matrix.RotateAt(Angle, TGPPointF.Create(150, 100), MatrixOrderAppend);
  Graphics.SetTransform(Matrix);

  (* Draw the image according to the transformation translated to it's center *)
  Graphics.DrawImage(Image,-imgWidth*0.5,-imgHeight*0.5, imgWidth, imgHeight);

  (* Reset the transformation in the matrix and the graphics *)
  Graphics.ResetTransform;
  Matrix.Reset;

  (* Set the new transformation *)
  Angle := 120.0;
  Matrix.Translate(100, 150);
  Matrix.RotateAt(Angle, TGPPointF.Create(100, 150), MatrixOrderAppend);
  Graphics.SetTransform(Matrix);

  (* Draw the next image according to the transformation translated to it's center *)
  Graphics.DrawImage(Image,-imgWidth*0.5,-imgHeight*0.5, imgWidth, imgHeight);

  (* Reset the transformation in the matrix and the graphics *)
  Graphics.ResetTransform;
  Matrix.Reset;
   
  (* aso *)

  (* Flush all the stuff to the canvas *)
  Graphics.Flush();
end;
Falls jemand eine einfachere Möglichkeit kennt, immer her damit

Gruß, alphaflight83
Make me a sandwich! - What? Make it yourself. - Sudo make me a sandwich! - Okay

Geändert von alphaflight83 (11. Feb 2011 um 10:09 Uhr) Grund: Anmerkungen
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#10

AW: Performanceproblem: Anzeige von Positionen mehrerer Clients

  Alt 11. Feb 2011, 16:22
@alphaflight83: dein Kommentarstil ist na ja, etwas "ineffizient".
Hier zwei Beispiele:
Delphi-Quellcode:
(* Lock the canvas *)
Canvas.Lock;

(* Flush all the stuff to the canvas *)
Graphics.Flush();
Diese Kommentare haben keine Aussagekraft und sind damit mehr schädlich als nützlich.
Soll heisen, man sollte keine Dinge kommentieren, die ganz offensichtlich aus dem Code hervorgehen.
Stattdessen würde ein mehrzeiliger Kommentar vor der Methode der in zwei Sätzen erklärt,
was hier passieren soll deutlich mehr Information an den Leser geben.

Ausserdem brauchst du für jede Kommentarzeile zu viel Schreibaufwand, weil du (* *) anstelle von // benützt.
Ich benütze Kommentare so:

Delphi-Quellcode:
// das ist ein Einzeiliger Kommentar

{
mehrzeile Kommentare
lassen sich gut mit geschweiften Klammern umsetzen.
diese Blöcke setze ich gerne vor Methoden um zu erklären
was der folgende Code tun soll
}


(* auskommentierter Code
if debug_flag then
  ShowMessageFmt('Anzahl=%d', [anz]);
*)
Styleguide > Kommentare

Und jetzt hätte ich noch eine Bitte an Alle:
bitte hier keine Diskussion über Kommentare im Sourcecode anfangen.
Andreas
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:50 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz