Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

CeDoMain

Alter Hase

  • »CeDoMain« ist der Autor dieses Themas

Beiträge: 587

Wohnort: Ilmenau

Beruf: Student für Mechatronik

  • Private Nachricht senden

1

15.06.2015, 22:50

[C# WPF] Datenbindung - Performance

Hallo Leute,

ich schreibe zurzeit ein Programm für Lichtsteuerung über DMX. Ich schreibe mir ein eigenes, weil ich ein Bedienungskonzept verfolge, das mir die auf dem Markt erhältlichen nicht zufriedenstellend bieten können. Klassendiagramm und Hard/Softwareverbindung zum DMX-Interface und damit meinen Lampen steht schon.

Ausschnitt aus meinem Klassendiagramm: Die höchste Klasse ist die Effektklasse (Lauflicht etc.), diese steuert die Funktionen (Farbe, Position) der Geräte (Dimmerpack, Moving-Head), die dann die Kanäle (0, 1, 2, ... , 512) im DMX-Interface aktualisieren.
Die Effektklasse wird von einem Timer aktualisiert, das bewirkt eine Kaskade von Methodenaufrufen, die letztendlich die DMX-Werte im Interface neu setzen. Das Ganze funktioniert auch schon wie gewollt schön schnell. Nun möchte ich eine GUI programmieren, die dem User die aktuellen Effekt-Zustände und Funktionswerte anzeigen. Eine OneWay-Bindung reich dazu aus.

Jetzt meine Frage: Wie soll mein Quellobjekt aussehen, damit auf keinen Fall die "Hintergrund-Kaskade" gebremst wird - eher soll die GUI langsamer geupdated werden! Zur Option stehen DependencyObject, INotifyPropertyChanged, das Updaten der Steuerelement-Eigenschaften mit Methodenaufrufen von der Kaskade aus und das Updaten der Eigenschaften z.B. jede 100ms durch einen Timer, der dann auch die Steuerelement-Eigenschaften manuell setzt. Wenn es noch andere (bessere) Möglichkeiten gibt: Immer heraus damit! ;)

Argumente für DependencyObject:
+ schnelles updaten der Bindung
+ wenig Speicherverbrauch
+ Man kann Animationen drauf anwenden
- Klasse muss von DependencyObject erben
- Abhängigkeit von WPF - portieren schwierig

Argumente für INotifyPropertyChanged:
+ keine Abhängigkeiten, sondern einfaches Event-System
+ "nur" eine Schnittstelle muss vererbt werden
- viel Speicherverbrauch (warum eigentlich?)
- langsames updaten der Bindung

Argumente für ein kaskadengesteuertes updaten der Eigenschaften (Bsp: Content, Text) direkt:
+ sehr kurzer Code
+ hohe Performance (Stimmt das?)
- Man muss das Updatesystem selber verwalten

Argumente für ein timergesteuertes updaten der Eigenschaften:
+ Die Kontrolle über die Häufigkeit der Updates liegt beim Programmierer
+ Damit kann die benötigte Leistung gut Kontrolliert bzw. eingeschrenkt werden

Wenn ich die Argumente so vergleiche, dann fliegt INotifyPropertyChanged ja leistungstechnisch sofort raus. Allerdings fehlen mir die Benchmarks (nennt man das so? :D ) für die Rechenpower die diese 4 Möglichkeiten benötigen, denn ich will ja nicht so die Leistung für die Datenbindung verbrauchen, sondern eher für meine Methodenkaskade, die mein DMX-Interface updatet!

Ich hoffe, einer von euch ist so mutig, kämpft sich durch meinen Text durch und kommt bei diesem Satz an... ;)

Danke für eure Mühe und dann hoffentlich konstruktive Vorschläge! ^^
Mit freundlichem Gruß
CeDo
Discord: #6996 | Skype: cedomain

Lass solche persönlichen Angriffe lieber bleiben, meine sind härter.

2

15.06.2015, 23:35

Hoi hoi,
ich habe zwar keine Ahnung von DMX, entwickle aber beruflich WPF-GUI´s. Hast du den vor das MVVM-Pattern zu nutzen oder nutzt du WPF wie ehemals WinForms ?

Gerade die Geschichte mit dem DataBinding macht eigentlich erst dann wirklich Sinn, wenn du die GUI in View und ViewModel unterteilst (Teil des MVVM-Pattern).
Dann befinden sich alle Properties welche das PropertyChanged-Event triggern im ViewModel und die entsprechenden Anzeigeelemente mit den Dependency Properties
an die gebunden wird in der View.

Ich kann nicht abschätzen, was genau du alles zwischen dem Updaten der Anzeigeelemente tun willst, aber ich kann mir nur schwer vorstellen, dass du dabei Probleme
hinsichtlich Timing bekommst. Gerade das erwähnte Updaten alle 100 ms .... 100 ms wären selbst für nen Microcontroller ne Ewigkeit.
WPF hat leider einen, meist unbegründet, schlechten Ruf hinsichtlich Performance. Für die meisten GUI-Anwendungen ist WPF performant genug.

Auf der arbeite lade ich beim Aufruf bestimmter Oberflächen teils 100 Objekte aus ner Datenbank und stecke sie in ne ObservableCollection die an eine ListView gebunden ist
und es ensteht keine spürbare Verzögerung zur Laufzeit.

Aber gerade wenn du nur sehr wenige Dinge im GUI anzeigen willst ist DataBinding oft "mit Kanonen auf Spatzen geschossen" und das klassische vorgehen (timergesteuertes updaten)
ist weitaus schneller und einfacher zu implementieren.
Dagegen ist Databinding, wenn es erst mal realisiert ist, sehr komfortabel.

Also würde ich dir raten erstmal zu überlegen ob du wirklich auf DataBinding angewiesen bist, wenn ja, halte dich (zumindest grob) ans MVVM-Pattern und setz es so um wie man
es in zich Tutorials erklärt bekommt.

Mfg !

3

15.06.2015, 23:56

Ah und noch ein Zusatz. Du sagtest ja dir wäre lieber die Ansteuerung der Lichter wird zuerst komplett abgearbeitet und die GUI updatet notfalls verzögert.
Auch das kannst du mittels DataBindnig ganz einfach dadurch erzwingen, dass du die PropertyChanged-Event eben nicht im Setter der Properties
triggerst, sondern erst dort wo sicher alles erledigt ist, was du vorher gerne abgearbeitet haben willst.

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

4

16.06.2015, 08:57

Warum das INotifyPropertyChanged für eine schlechtere Performance sorgen soll, ist mir rätselhaft. (Siehe dazu auch eine Frage auf Stackoverflow (vor allem die 1. Antwort)
Und was macht deine Anwendung bitte, dass Bedenken über die Performance relevant sein sollten? Bisher klingt es nicht so, als würden die Verarbeitungsschritte besonders lange brauchen.
Wenn die Abhängigkeit zu WPF ein zu großes Problem darstellt, dann solltest du die Interfaceimplementierung wählen.

@QuickAndDirty:
WPF ist genauso Ressourcenverschwendend, wie Unity nicht für 2D Spiele geeignet ist. ;)
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

CeDoMain

Alter Hase

  • »CeDoMain« ist der Autor dieses Themas

Beiträge: 587

Wohnort: Ilmenau

Beruf: Student für Mechatronik

  • Private Nachricht senden

5

16.06.2015, 17:07

Schonmal vielen Dank für eure hilfreichen Antworten! :)

@QuickAndDirty: Ja, ich habe das MVVM-Pattern wie es beschrieben ist, implementiert. Ich trenne zwischen den WPF-Controls und meinen Hintergrundklassen. Allerdings habe ich nur eine Zweiteilung und keine Dreiteilung - das ViewModel in der "Mitte" fehlt bei mir. Ist das schlimm? Zu den 100 ms: Das ist die minimale Bildrate, die ich erwarte. Die Kaskade wird sehr viel häufiger ausgelöst - so 100 mal pro Sekunde pro Effekt. Und wenn dann 20 gleichzeitig laufen, dann ist das doch schon eine ganze Menge oder?

@Sacaldur: Mein Klassendiagramm ist ein bisschen unvollständig - die Effekte können nämlich beliebig parametrisiert werden, dann können Effekte auch andere Effekte steuern. Das kann dann ganz schnell zu finde ich sehr vielen Berechnungen kommen.

Mir gings jetzt nicht hauptsächlich um die Performance der Bindung an sich, sondern die Rechenleistung, die mir dadurch dann nicht mehr für die Kaskade zur Verfügung steht... Genau dazu finde ich ja nichts im INET. Zur Bindungsperformance selber gibts ja ne Menge, wie angemerkt wurde.

Ich denke, dass ich mich für INotifyPropertyChanged entscheide, weil das finde ich kleiner ist und mich die Vererbung von einem DependencyObject stört! Und um Animationen nutzen zu können, kann ich ja immernoch in einer Effektklasse DependencyProperties einsetzen.
Mit freundlichem Gruß
CeDo
Discord: #6996 | Skype: cedomain

Lass solche persönlichen Angriffe lieber bleiben, meine sind härter.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

16.06.2015, 17:18

Ich trenne zwischen den WPF-Controls und meinen Hintergrundklassen.
Also benutzt Du WPF als als wäre es WinForms. Das is natürlich sehr schade.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

7

16.06.2015, 17:40

Ich trenne zwischen den WPF-Controls und meinen Hintergrundklassen.
Also benutzt Du WPF als als wäre es WinForms. Das is natürlich sehr schade.
Das muss nicht mal der Fall sein. Mit der Trennung kann auch einfach nur die Unterteilung in unterschiedliche Namespaces gemeint sein, die entsprechend in unterschiedlichen Projektverzeichnissen liegen. Genau das wäre wieder gut.
Und ich würde aus einem von ihm geschriebenen Satz auf die Verwendung von Databinding schließen:
Ich denke, dass ich mich für INotifyPropertyChanged entscheide, ...


@CeDoMain:
Um vergleichswerte zu haben, sollte man sich andere Stellen mit vielen Berechnungen ansehen: physikalische Berechnungen, 3D-Berechnungen, Manipulation von Grafiken usw. (wobei es bei allen immernoch auf den Umfang ankommt).
Auch wenn die Effekte verschachtelt sind, klingt das (für mich) noch nicht besonders umfangreich.
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

Legend

Alter Hase

Beiträge: 731

Beruf: Softwareentwickler

  • Private Nachricht senden

8

16.06.2015, 17:47

Zitat

Argumente für ein kaskadengesteuertes updaten der Eigenschaften (Bsp: Content, Text) direkt:
+ sehr kurzer Code


Was? Höchstens bei nem Minibeispiel. Wenn du ein größeres Projekt hast schreibst du entweder eine Methode die alles updated (langsam) oder dein Code wird schnell ausufern wenn zwischen Controls inhaltliche Abhängigkeiten bestehen. Und dann hast du sehr viel Code.
"Wir müssen uns auf unsere Kernkompetenzen konzentrieren!" - "Juhu, wir machen eine Farm auf!"

Netzwerkbibliothek von mir, C#, LGPL: https://sourceforge.net/projects/statetransmitt/

CeDoMain

Alter Hase

  • »CeDoMain« ist der Autor dieses Themas

Beiträge: 587

Wohnort: Ilmenau

Beruf: Student für Mechatronik

  • Private Nachricht senden

9

16.06.2015, 17:53

@BlueCobold & Sacaldur: Ich versuche mal Licht ins Dunkel zu bringen: Die Eigenschaften meiner Klassen, die ich in WPF anzeigen möchte, habe ich jetzt mit "INotifyPropertyChanged-Logik" versehen. Die GUI enthält im Code-Behind eine ObservableCollection, mit mehreren Klassenobjekten. In XAML programmiere ich dann DataTemplates, die die Klassen anzeigen können, indem sie Steuerelemente mit {Binding Path=PropertyName} an meine Klasse binden. Dann binde ich ein ItemsControl an die ObservableCollection, dass mir die Klassen dann anzeigt. So habe ich MVVM verstanden!?

Sorry, wenn mein
Ich trenne zwischen den WPF-Controls und meinen Hintergrundklassen.
ein bisschen irreführend formuliert war...

Ich probiere es jetzt einfach mal aus, wie gut das Ganze mit INPC funktioniert. :) Danke für eure Ratschläge!
Mit freundlichem Gruß
CeDo
Discord: #6996 | Skype: cedomain

Lass solche persönlichen Angriffe lieber bleiben, meine sind härter.

CeDoMain

Alter Hase

  • »CeDoMain« ist der Autor dieses Themas

Beiträge: 587

Wohnort: Ilmenau

Beruf: Student für Mechatronik

  • Private Nachricht senden

10

16.06.2015, 18:00

Was? Höchstens bei nem Minibeispiel. Wenn du ein größeres Projekt hast schreibst du entweder eine Methode die alles updated (langsam) oder dein Code wird schnell ausufern wenn zwischen Controls inhaltliche Abhängigkeiten bestehen. Und dann hast du sehr viel Code.
Der Stichpunkt war auf den Update-Befehl selbst bezogen. Ich denke nicht, dass ich sowas gemacht hätte, denn es wird bestimmt in Unübersichtlichkeit ausufern - da geb ich dir Recht!
Mit freundlichem Gruß
CeDo
Discord: #6996 | Skype: cedomain

Lass solche persönlichen Angriffe lieber bleiben, meine sind härter.

Werbeanzeige